home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Plotting / aa_Intel_Only / Gnuplot / GnuplotSource / setshow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  73.6 KB  |  3,003 lines

  1. static char *RCSid = "$Id: setshow.c%v 3.38.2.119 1993/04/26 00:02:13 woo Exp woo $";
  2.  
  3.  
  4. /* GNUPLOT - setshow.c */
  5. /*
  6.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  7.  *
  8.  * Permission to use, copy, and distribute this software and its
  9.  * documentation for any purpose with or without fee is hereby granted, 
  10.  * provided that the above copyright notice appear in all copies and 
  11.  * that both that copyright notice and this permission notice appear 
  12.  * in supporting documentation.
  13.  *
  14.  * Permission to modify the software is granted, but not the right to
  15.  * distribute the modified code.  Modifications are to be distributed 
  16.  * as patches to released version.
  17.  *  
  18.  * This software is provided "as is" without express or implied warranty.
  19.  * 
  20.  *
  21.  * AUTHORS
  22.  * 
  23.  *   Original Software:
  24.  *     Thomas Williams,  Colin Kelley.
  25.  * 
  26.  *   Gnuplot 2.0 additions:
  27.  *       Russell Lang, Dave Kotz, John Campbell.
  28.  *
  29.  *   Gnuplot 3.0 additions:
  30.  *       Gershon Elber and many others.
  31.  *
  32.  * 19 September 1992  Lawrence Crowl  (crowl@cs.orst.edu)
  33.  * Added user-specified bases for log scaling.
  34.  * 
  35.  * Send your comments or suggestions to 
  36.  *  info-gnuplot@dartmouth.edu.
  37.  * This is a mailing list; to join it send a note to 
  38.  *  info-gnuplot-request@dartmouth.edu.  
  39.  * Send bug reports to
  40.  *  bug-gnuplot@dartmouth.edu.
  41.  */
  42.  
  43. #include <stdio.h>
  44. #include <math.h>
  45. #include "plot.h"
  46. #include "setshow.h"
  47.  
  48. #define DEF_FORMAT   "%g"    /* default format for tic mark labels */
  49. #define SIGNIF (0.01)        /* less than one hundredth of a tic mark */
  50.  
  51. /*
  52.  * global variables to hold status of 'set' options
  53.  *
  54.  */
  55. TBOOLEAN        autoscale_r    = TRUE;
  56. TBOOLEAN        autoscale_t    = TRUE;
  57. TBOOLEAN        autoscale_u    = TRUE;
  58. TBOOLEAN        autoscale_v    = TRUE;
  59. TBOOLEAN        autoscale_x    = TRUE;
  60. TBOOLEAN        autoscale_y    = TRUE;
  61. TBOOLEAN        autoscale_z    = TRUE;
  62. TBOOLEAN        autoscale_lt    = TRUE;
  63. TBOOLEAN        autoscale_lu    = TRUE;
  64. TBOOLEAN        autoscale_lv    = TRUE;
  65. TBOOLEAN        autoscale_lx    = TRUE;
  66. TBOOLEAN        autoscale_ly    = TRUE;
  67. TBOOLEAN        autoscale_lz    = TRUE;
  68. double            boxwidth    = -1.0; /* box width (automatic) */
  69. TBOOLEAN         clip_points    = FALSE;
  70. TBOOLEAN         clip_lines1    = TRUE;
  71. TBOOLEAN         clip_lines2    = FALSE;
  72. TBOOLEAN        draw_border    = TRUE;
  73. TBOOLEAN        draw_surface    = TRUE;
  74. TBOOLEAN        timedate    = FALSE;
  75. char            dummy_var[MAX_NUM_VAR][MAX_ID_LEN+1] = { "x", "y" };
  76. char            xformat[MAX_ID_LEN+1] = DEF_FORMAT;
  77. char            yformat[MAX_ID_LEN+1] = DEF_FORMAT;
  78. char            zformat[MAX_ID_LEN+1] = DEF_FORMAT;
  79. enum PLOT_STYLE        data_style    = POINTSTYLE;
  80. enum PLOT_STYLE        func_style    = LINES;
  81. TBOOLEAN        grid        = FALSE;
  82. int            key        = -1;    /* default position */
  83. double            key_x;
  84. double            key_y;    /* user specified position for key */
  85. double            key_z;
  86. TBOOLEAN        is_log_x    = FALSE;
  87. TBOOLEAN        is_log_y    = FALSE;
  88. TBOOLEAN        is_log_z    = FALSE;
  89. double            base_log_x    = 0.0;
  90. double            base_log_y    = 0.0;
  91. double            base_log_z    = 0.0;
  92. double            log_base_log_x    = 0.0;
  93. double            log_base_log_y    = 0.0;
  94. double            log_base_log_z    = 0.0;
  95. FILE*            outfile;
  96. char            outstr[MAX_ID_LEN+1] = "STDOUT";
  97. TBOOLEAN        parametric    = FALSE;
  98. TBOOLEAN        polar        = FALSE;
  99. TBOOLEAN        hidden3d    = FALSE;
  100. TBOOLEAN        label_contours    = TRUE; /* different linestyles are used for contours when set */
  101. int            angles_format    = ANGLES_RADIANS;
  102. int            mapping3d    = MAP3D_CARTESIAN;
  103. int            samples        = SAMPLES; /* samples is always equal to samples_1 */
  104. int            samples_1    = SAMPLES;
  105. int            samples_2    = SAMPLES;
  106. int            iso_samples_1    = ISO_SAMPLES;
  107. int            iso_samples_2    = ISO_SAMPLES;
  108. float            xsize        = 1.0;  /* scale factor for size */
  109. float            ysize        = 1.0;  /* scale factor for size */
  110. float            zsize        = 1.0;  /* scale factor for size */
  111. float            surface_rot_z   = 30.0; /* Default 3d transform. */
  112. float            surface_rot_x   = 60.0;
  113. float            surface_scale   = 1.0;
  114. float            surface_zscale  = 1.0;
  115. int            term        = 0;        /* unknown term is 0 */
  116. char            term_options[MAX_LINE_LEN+1] = "";
  117. char            title[MAX_LINE_LEN+1] = "";
  118. char            xlabel[MAX_LINE_LEN+1] = "";
  119. char            ylabel[MAX_LINE_LEN+1] = "";
  120. char            zlabel[MAX_LINE_LEN+1] = "";
  121. int            time_xoffset    = 0;
  122. int            time_yoffset    = 0;
  123. int            title_xoffset    = 0;
  124. int            title_yoffset    = 0;
  125. int            xlabel_xoffset    = 0;
  126. int            xlabel_yoffset    = 0;
  127. int            ylabel_xoffset    = 0;
  128. int            ylabel_yoffset    = 0;
  129. int            zlabel_xoffset    = 0;
  130. int            zlabel_yoffset    = 0;
  131. double            rmin        = -0.0;
  132. double            rmax        =  10.0;
  133. double            tmin        = -5.0;
  134. double            tmax        =  5.0;
  135. double            umin        = -5.0;
  136. double            umax        = 5.0;
  137. double            vmin        = -5.0;
  138. double            vmax        = 5.0;
  139. double            xmin        = -10.0;
  140. double            xmax        = 10.0;
  141. double            ymin        = -10.0;
  142. double            ymax        = 10.0;
  143. double            zmin        = -10.0;
  144. double            zmax        = 10.0;
  145. double            loff        = 0.0;
  146. double            roff        = 0.0;
  147. double            toff        = 0.0;
  148. double            boff        = 0.0;
  149. int            draw_contour    = CONTOUR_NONE;
  150. int            contour_pts    = 5;
  151. int            contour_kind    = CONTOUR_KIND_LINEAR;
  152. int            contour_order    = 4;
  153. int            contour_levels    = 5;
  154. double            zero        = ZERO;    /* zero threshold, not 0! */
  155. int            levels_kind    = LEVELS_AUTO;
  156. double            levels_list[MAX_DISCRETE_LEVELS];  /* storage for z levels to draw contours at */
  157.  
  158. int            dgrid3d_row_fineness = 10;
  159. int            dgrid3d_col_fineness = 10;
  160. int            dgrid3d_norm_value = 1;
  161. TBOOLEAN        dgrid3d        = FALSE;
  162.  
  163. TBOOLEAN         xzeroaxis    = TRUE;
  164. TBOOLEAN         yzeroaxis    = TRUE;
  165.  
  166. TBOOLEAN         xtics        = TRUE;
  167. TBOOLEAN         ytics        = TRUE;
  168. TBOOLEAN         ztics        = TRUE;
  169.  
  170. float             ticslevel    = 0.5;
  171.  
  172. struct ticdef        xticdef        = {TIC_COMPUTED};
  173. struct ticdef        yticdef        = {TIC_COMPUTED};
  174. struct ticdef        zticdef        = {TIC_COMPUTED};
  175.  
  176. TBOOLEAN        tic_in        = TRUE;
  177.  
  178. struct text_label     *first_label    = NULL;
  179. struct arrow_def     *first_arrow    = NULL;
  180.  
  181. /*** other things we need *****/
  182. #ifdef _Windows
  183. #include <string.h>
  184. #else
  185. #if !defined(ATARI) && !defined (AMIGA_SC_6_1)
  186. extern char *strcpy(),*strcat();
  187. extern int strlen();
  188. #endif
  189. #endif
  190.  
  191. #if defined(unix) || defined(PIPES)
  192. extern FILE *popen();
  193. #endif
  194.  
  195. /* input data, parsing variables */
  196. extern struct lexical_unit token[];
  197. extern char input_line[];
  198. extern int num_tokens, c_token;
  199. extern TBOOLEAN interactive;    /* from plot.c */
  200.  
  201. extern char replot_line[];
  202. extern struct udvt_entry *first_udv;
  203. extern TBOOLEAN is_3d_plot;
  204.  
  205. extern double magnitude(),real();
  206. extern struct value *const_express();
  207.  
  208. #ifdef _Windows
  209. extern FILE * open_printer();
  210. extern void close_printer();
  211. #endif
  212.  
  213. /******** Local functions ********/
  214. static void set_xyzlabel();
  215. static void set_label();
  216. static void set_nolabel();
  217. static void set_arrow();
  218. static void set_noarrow();
  219. static void load_tics();
  220. static void load_tic_user();
  221. static void free_marklist();
  222. static void load_tic_series();
  223. static void load_offsets();
  224.  
  225. static void show_style(), show_range(), show_zero(), show_border(), show_dgrid3d();
  226. static void show_offsets(), show_output(), show_samples(), show_isosamples();
  227. static void show_view(), show_size(), show_title(), show_xlabel();
  228. static void show_angles(), show_boxwidth();
  229. static void show_ylabel(), show_zlabel(), show_xzeroaxis(), show_yzeroaxis();
  230. static void show_label(), show_arrow(), show_grid(), show_key();
  231. static void show_polar(), show_parametric(), show_tics(), show_ticdef();
  232. static void show_time(), show_term(), show_plot(), show_autoscale(), show_clip();
  233. static void show_contour(), show_mapping(), show_format(), show_logscale();
  234. static void show_variables(), show_surface(), show_hidden3d(), show_label_contours();
  235. static void delete_label();
  236. static int assign_label_tag();
  237. static void delete_arrow();
  238. static int assign_arrow_tag();
  239. static TBOOLEAN set_one(), set_two(), set_three();
  240. static TBOOLEAN show_one(), show_two();
  241.  
  242. /******** The 'set' command ********/
  243. void
  244. set_command()
  245. {
  246.     c_token++;
  247.  
  248.     if (!set_one() && !set_two() && !set_three())
  249.     int_error(
  250.     "valid set options:  'angles' '{no}arrow', {no}autoscale', \n\
  251.     '{no}border', 'boxwidth', '{no}clabel', '{no}clip', 'cntrparam', \n\
  252.         '{no}contour', 'data style', '{no}dgrid3d', 'dummy', 'format', \n\
  253.         'function style', '{no}grid', '{no}hidden3d', 'isosamples', '{no}key', \n\
  254.     '{no}label', '{no}logscale', 'mapping', 'offsets', 'output', \n\
  255.     '{no}parametric', '{no}polar', 'rrange', 'samples', 'size', \n\
  256.     '{no}surface', 'terminal', 'tics', 'ticslevel', '{no}time', 'title', \n\
  257.     'trange', 'urange', 'view', 'vrange', 'xlabel', 'xrange', '{no}xtics', \n\
  258.     'xmtics', 'xdtics', '{no}xzeroaxis', 'ylabel', 'yrange', '{no}ytics', \n\
  259.     'ymtics', 'ydtics', '{no}yzeroaxis', 'zero', '{no}zeroaxis', 'zlabel', \n\
  260.     'zrange', '{no}ztics', 'zmtics', 'zdtics'", c_token);
  261. }
  262.  
  263. /* return TRUE if a command match, FALSE if not */
  264. static TBOOLEAN
  265. set_one()
  266. {
  267.     if (almost_equals(c_token,"ar$row")) {
  268.         c_token++;
  269.         set_arrow();
  270.     }
  271.     else if (almost_equals(c_token,"noar$row")) {
  272.         c_token++;
  273.         set_noarrow();
  274.     }
  275.      else if (almost_equals(c_token,"au$toscale")) {
  276.         c_token++;
  277.         if (END_OF_COMMAND) {
  278.            autoscale_r=autoscale_t = autoscale_x = autoscale_y = autoscale_z = TRUE;
  279.         } else if (equals(c_token, "xy") || equals(c_token, "yx")) {
  280.            autoscale_x = autoscale_y = TRUE;
  281.            c_token++;
  282.         } else if (equals(c_token, "r")) {
  283.            autoscale_r = TRUE;
  284.            c_token++;
  285.         } else if (equals(c_token, "t")) {
  286.            autoscale_t = TRUE;
  287.            c_token++;
  288.         } else if (equals(c_token, "x")) {
  289.            autoscale_x = TRUE;
  290.            c_token++;
  291.         } else if (equals(c_token, "y")) {
  292.            autoscale_y = TRUE;
  293.            c_token++;
  294.         } else if (equals(c_token, "z")) {
  295.            autoscale_z = TRUE;
  296.            c_token++;
  297.         }
  298.     } 
  299.     else if (almost_equals(c_token,"noau$toscale")) {
  300.         c_token++;
  301.         if (END_OF_COMMAND) {
  302.            autoscale_r=autoscale_t = autoscale_x = autoscale_y = autoscale_z = FALSE;
  303.         } else if (equals(c_token, "xy") || equals(c_token, "tyx")) {
  304.            autoscale_x = autoscale_y = FALSE;
  305.            c_token++;
  306.         } else if (equals(c_token, "r")) {
  307.            autoscale_r = FALSE;
  308.            c_token++;
  309.         } else if (equals(c_token, "t")) {
  310.            autoscale_t = FALSE;
  311.            c_token++;
  312.         } else if (equals(c_token, "x")) {
  313.            autoscale_x = FALSE;
  314.            c_token++;
  315.         } else if (equals(c_token, "y")) {
  316.            autoscale_y = FALSE;
  317.            c_token++;
  318.         } else if (equals(c_token, "z")) {
  319.            autoscale_z = FALSE;
  320.            c_token++;
  321.         }
  322.     } 
  323.     else if (almost_equals(c_token,"bor$der")) {
  324.         draw_border = TRUE;
  325.         c_token++;
  326.     }
  327.     else if (almost_equals(c_token,"nobor$der")) {
  328.         draw_border = FALSE;
  329.         c_token++;
  330.     }
  331.     else if (almost_equals(c_token,"box$width")) {
  332.         struct value a;
  333.         c_token++;
  334.         if (END_OF_COMMAND)
  335.             boxwidth = -1.0;
  336.         else
  337.             boxwidth = magnitude(const_express(&a));
  338.     }
  339.     else if (almost_equals(c_token,"c$lip")) {
  340.         c_token++;
  341.         if (END_OF_COMMAND)
  342.          /* assuming same as points */
  343.          clip_points = TRUE;
  344.         else if (almost_equals(c_token, "p$oints"))
  345.          clip_points = TRUE;
  346.         else if (almost_equals(c_token, "o$ne"))
  347.          clip_lines1 = TRUE;
  348.         else if (almost_equals(c_token, "t$wo"))
  349.          clip_lines2 = TRUE;
  350.         else
  351.          int_error("expecting 'points', 'one', or 'two'", c_token);
  352.         c_token++;
  353.     }
  354.     else if (almost_equals(c_token,"noc$lip")) {
  355.         c_token++;
  356.         if (END_OF_COMMAND) {
  357.            /* same as all three */
  358.            clip_points = FALSE;
  359.            clip_lines1 = FALSE;
  360.            clip_lines2 = FALSE;
  361.         } else if (almost_equals(c_token, "p$oints"))
  362.          clip_points = FALSE;
  363.         else if (almost_equals(c_token, "o$ne"))
  364.          clip_lines1 = FALSE;
  365.         else if (almost_equals(c_token, "t$wo"))
  366.          clip_lines2 = FALSE;
  367.         else
  368.          int_error("expecting 'points', 'one', or 'two'", c_token);
  369.         c_token++;
  370.     }
  371.     else if (almost_equals(c_token,"hi$dden3d")) {
  372. #ifdef LITE
  373.         printf(" Hidden Line Removal Not Supported in LITE version\n");
  374. #else
  375.         hidden3d = TRUE;
  376. #endif /* LITE */
  377.         c_token++;
  378.     }
  379.     else if (almost_equals(c_token,"nohi$dden3d")) {
  380. #ifdef LITE
  381.         printf(" Hidden Line Removal Not Supported in LITE version\n");
  382. #else
  383.         hidden3d = FALSE;
  384. #endif /* LITE */
  385.         c_token++;
  386.     }
  387.      else if (almost_equals(c_token,"cla$bel")) {
  388.          label_contours = TRUE;
  389.          c_token++;
  390.      }
  391.      else if (almost_equals(c_token,"nocla$bel")) {
  392.          label_contours = FALSE;
  393.          c_token++;
  394.       }
  395.     else if (almost_equals(c_token,"ma$pping3d")) {
  396.         c_token++;
  397.         if (END_OF_COMMAND)
  398.          /* assuming same as points */
  399.          mapping3d = MAP3D_CARTESIAN;
  400.         else if (almost_equals(c_token, "ca$rtesian"))
  401.          mapping3d = MAP3D_CARTESIAN;
  402.         else if (almost_equals(c_token, "s$pherical"))
  403.          mapping3d = MAP3D_SPHERICAL;
  404.         else if (almost_equals(c_token, "cy$lindrical"))
  405.          mapping3d = MAP3D_CYLINDRICAL;
  406.         else
  407.          int_error("expecting 'cartesian', 'spherical', or 'cylindrical'", c_token);
  408.         c_token++;
  409.     }
  410.     else if (almost_equals(c_token,"co$ntour")) {
  411.         c_token++;
  412.         if (END_OF_COMMAND)
  413.          /* assuming same as points */
  414.          draw_contour = CONTOUR_BASE;
  415.         else if (almost_equals(c_token, "ba$se"))
  416.          draw_contour = CONTOUR_BASE;
  417.         else if (almost_equals(c_token, "s$urface"))
  418.          draw_contour = CONTOUR_SRF;
  419.         else if (almost_equals(c_token, "bo$th"))
  420.          draw_contour = CONTOUR_BOTH;
  421.         else
  422.          int_error("expecting 'base', 'surface', or 'both'", c_token);
  423.         c_token++;
  424.     }
  425.     else if (almost_equals(c_token,"noco$ntour")) {
  426.         c_token++;
  427.         draw_contour = CONTOUR_NONE;
  428.     }
  429.     else if (almost_equals(c_token,"cntrp$aram")) {
  430.         struct value a;
  431.  
  432.         c_token++;
  433.         if (END_OF_COMMAND) {
  434.          /* assuming same as defaults */
  435.          contour_pts = 5;
  436.          contour_kind = CONTOUR_KIND_LINEAR;
  437.          contour_order = 4;
  438.          contour_levels = 5;
  439.           levels_kind = LEVELS_AUTO;
  440.         }
  441.         else if (almost_equals(c_token, "p$oints")) {
  442.          c_token++;
  443.          contour_pts = (int) real(const_express(&a));
  444.         }
  445.         else if (almost_equals(c_token, "li$near")) {
  446.          c_token++;
  447.          contour_kind = CONTOUR_KIND_LINEAR;
  448.         }
  449.         else if (almost_equals(c_token, "c$ubicspline")) {
  450.          c_token++;
  451.          contour_kind = CONTOUR_KIND_CUBIC_SPL;
  452.         }
  453.         else if (almost_equals(c_token, "b$spline")) {
  454.          c_token++;
  455.          contour_kind = CONTOUR_KIND_BSPLINE;
  456.         }
  457.  
  458.            else if (almost_equals(c_token, "le$vels")) {
  459.                int i=0;  /* local counter */
  460.                c_token++;
  461.             /*  RKC: I have modified the next two:
  462.              *   to use commas to separate list elements as in xtics
  463.               *   so that incremental lists start,incr[,end]as in "
  464.               */
  465.                if (almost_equals(c_token, "di$screte")) {
  466.                   levels_kind = LEVELS_DISCRETE;
  467.                   c_token++;
  468.                 if(END_OF_COMMAND)
  469.                  int_error("expecting discrete level", c_token);
  470.                 else
  471.                   levels_list[i++] = real(const_express(&a));
  472.                 while(!END_OF_COMMAND){
  473.                   if (!equals(c_token, ","))
  474.                     int_error("expecting comma to separate discrete levels", c_token);
  475.                   c_token++;
  476.                   levels_list[i++] =  real(const_express(&a));
  477.                 }
  478.                   contour_levels = i;
  479.                }
  480.                else if (almost_equals(c_token, "in$cremental")) {
  481.                   levels_kind = LEVELS_INCREMENTAL;
  482.                   c_token++;
  483.                 levels_list[i++] =  real(const_express(&a));
  484.                 if (!equals(c_token, ","))
  485.                   int_error("expecting comma to separate start,incr levels", c_token);
  486.                 c_token++;
  487.                 if((levels_list[i++] = real(const_express(&a)))==0)
  488.                   int_error("increment cannot be 0", c_token);
  489.                  if(!END_OF_COMMAND){
  490.                   if (!equals(c_token, ","))
  491.                     int_error("expecting comma to separate incr,stop levels", c_token);
  492.                   c_token++;
  493.                  contour_levels = (real(const_express(&a))-levels_list[0])/levels_list[1];
  494.                   }
  495.                }
  496.                else if (almost_equals(c_token, "au$to")) {
  497.                    levels_kind = LEVELS_AUTO;
  498.                  c_token++;
  499.                  if(!END_OF_COMMAND)
  500.                      contour_levels = (int) real(const_express(&a));
  501.              }
  502.              else {
  503.               if(levels_kind == LEVELS_DISCRETE)
  504.                 int_error("Levels type is discrete, ignoring new number of contour levels", c_token);
  505.                 contour_levels = (int) real(const_express(&a));
  506.             }
  507.          }
  508.         else if (almost_equals(c_token, "o$rder")) {
  509.          int order;
  510.          c_token++;
  511.          order = (int) real(const_express(&a));
  512.          if ( order < 2 || order > 10 )
  513.              int_error("bspline order must be in [2..10] range.", c_token);
  514.          contour_order = order;
  515.         }
  516.         else
  517.          int_error("expecting 'linear', 'cubicspline', 'bspline', 'points', 'levels' or 'order'", c_token);
  518.         c_token++;
  519.     }
  520.     else if (almost_equals(c_token,"da$ta")) {
  521.         c_token++;
  522.         if (!almost_equals(c_token,"s$tyle"))
  523.             int_error("expecting keyword 'style'",c_token);
  524.         data_style = get_style();
  525.     }
  526.     else if (almost_equals(c_token,"dg$rid3d")) {
  527.         int i;
  528.         TBOOLEAN was_comma = TRUE;
  529.         int local_vals[3];
  530.         struct value a;
  531.  
  532.         local_vals[0] = dgrid3d_row_fineness;
  533.         local_vals[1] = dgrid3d_col_fineness;
  534.         local_vals[2] = dgrid3d_norm_value;
  535.         c_token++;
  536.         for (i = 0; i < 3 && !(END_OF_COMMAND);) {
  537.             if (equals(c_token,",")) {
  538.                 if (was_comma) i++;
  539.                 was_comma = TRUE;
  540.                 c_token++;
  541.             }
  542.             else {
  543.                 if (!was_comma)
  544.                     int_error("',' expected",c_token);
  545.                 local_vals[i] = real(const_express(&a));
  546.                 i++;
  547.                 was_comma = FALSE;
  548.             }
  549.         }
  550.  
  551.  
  552.         if (local_vals[0] < 2 || local_vals[0] > 1000)
  553.             int_error("Row size must be in [2:1000] range; size unchanged",
  554.                   c_token);
  555.         if (local_vals[1] < 2 || local_vals[1] > 1000)
  556.             int_error("Col size must be in [2:1000] range; size unchanged",
  557.                   c_token);
  558.         if (local_vals[2] < 1 || local_vals[2] > 100)
  559.             int_error("Norm must be in [1:100] range; norm unchanged", c_token);
  560.  
  561.         dgrid3d_row_fineness = local_vals[0];
  562.         dgrid3d_col_fineness = local_vals[1];
  563.         dgrid3d_norm_value = local_vals[2];
  564.         dgrid3d = TRUE;
  565.     }
  566.     else if (almost_equals(c_token,"nodg$rid3d")) {
  567.         c_token++;
  568.         dgrid3d = FALSE;
  569.     }
  570.     else if (almost_equals(c_token,"du$mmy")) {
  571.         c_token++;
  572.         if (END_OF_COMMAND)
  573.             int_error("expecting dummy variable name", c_token);
  574.         else {
  575.             if (!equals(c_token,","))
  576.                 copy_str(dummy_var[0],c_token++);
  577.             if (!END_OF_COMMAND && equals(c_token,",")) {
  578.                 c_token++;
  579.                 if (END_OF_COMMAND)
  580.                     int_error("expecting second dummy variable name", c_token);
  581.                 copy_str(dummy_var[1],c_token++);
  582.                 }
  583.         }
  584.     }
  585.     else if (almost_equals(c_token,"fo$rmat")) {
  586.         TBOOLEAN setx, sety, setz;
  587.         c_token++;
  588.         if (equals(c_token,"x")) {
  589.             setx = TRUE; sety = setz = FALSE;
  590.             c_token++;
  591.         }
  592.         else if (equals(c_token,"y")) {
  593.             setx = setz = FALSE; sety = TRUE;
  594.             c_token++;
  595.         }
  596.         else if (equals(c_token,"z")) {
  597.             setx = sety = FALSE; setz = TRUE;
  598.             c_token++;
  599.         }
  600.         else if (equals(c_token,"xy") || equals(c_token,"yx")) {
  601.             setx = sety = TRUE; setz = FALSE;
  602.             c_token++;
  603.         }
  604.         else if (isstring(c_token) || END_OF_COMMAND) {
  605.             /* Assume he wants all */
  606.             setx = sety = setz = TRUE;
  607.         }
  608.         if (END_OF_COMMAND) {
  609.             if (setx)
  610.                 (void) strcpy(xformat,DEF_FORMAT);
  611.             if (sety)
  612.                 (void) strcpy(yformat,DEF_FORMAT);
  613.             if (setz)
  614.                 (void) strcpy(zformat,DEF_FORMAT);
  615.         }
  616.         else {
  617.             if (!isstring(c_token))
  618.               int_error("expecting format string",c_token);
  619.             else {
  620.                 if (setx)
  621.                  quote_str(xformat,c_token);
  622.                 if (sety)
  623.                  quote_str(yformat,c_token);
  624.                 if (setz)
  625.                  quote_str(zformat,c_token);
  626.                 c_token++;
  627.             }
  628.         }
  629.     }
  630.     else if (almost_equals(c_token,"fu$nction")) {
  631.         c_token++;
  632.         if (!almost_equals(c_token,"s$tyle"))
  633.             int_error("expecting keyword 'style'",c_token);
  634.         func_style = get_style();
  635.     }
  636.     else if (almost_equals(c_token,"la$bel")) {
  637.         c_token++;
  638.         set_label();
  639.     }
  640.     else if (almost_equals(c_token,"nola$bel")) {
  641.         c_token++;
  642.         set_nolabel();
  643.     }
  644.     else if (almost_equals(c_token,"lo$gscale")) {
  645.         c_token++;
  646.         if (END_OF_COMMAND) {
  647.         is_log_x = is_log_y = is_log_z = TRUE;
  648.         base_log_x = base_log_y = base_log_z = 10.0;
  649.         log_base_log_x = log_base_log_y = log_base_log_z = log(10.0);
  650.         } else {
  651.         TBOOLEAN change_x = FALSE;
  652.         TBOOLEAN change_y = FALSE;
  653.         TBOOLEAN change_z = FALSE;
  654.         if (chr_in_str(c_token, 'x'))
  655.             change_x = TRUE;
  656.         if (chr_in_str(c_token, 'y'))
  657.             change_y = TRUE;
  658.         if (chr_in_str(c_token, 'z'))
  659.             change_z = TRUE;
  660.         c_token++;
  661.                 if (END_OF_COMMAND) {
  662.             if (change_x) {
  663.             is_log_x = TRUE;
  664.             base_log_x = 10.0;
  665.             log_base_log_x = log(10.0);
  666.             }
  667.             if (change_y) {
  668.             is_log_y = TRUE;
  669.             base_log_y = 10.0;
  670.             log_base_log_y = log(10.0);
  671.             }
  672.             if (change_z) {
  673.             is_log_z = TRUE;
  674.             base_log_z = 10.0;
  675.             log_base_log_z = log(10.0);
  676.             }
  677.         } else {
  678.             struct value a;
  679.             double newbase = magnitude(const_express(&a));
  680.             c_token++;
  681.             if (newbase < 1.1)
  682.             int_error("log base must be >= 1.1; logscale unchanged",
  683.                 c_token);
  684.             else {
  685.             if (change_x) {
  686.                 is_log_x = TRUE;
  687.                 base_log_x = newbase;
  688.                 log_base_log_x = log(newbase);
  689.             }
  690.             if (change_y) {
  691.                 is_log_y = TRUE;
  692.                 base_log_y = newbase;
  693.                 log_base_log_y = log(newbase);
  694.             }
  695.             if (change_z) {
  696.                 is_log_z = TRUE;
  697.                 base_log_z = newbase;
  698.                 log_base_log_z = log(newbase);
  699.             }
  700.             }
  701.         }
  702.         }
  703.     }
  704.     else if (almost_equals(c_token,"nolo$gscale")) {
  705.         c_token++;
  706.         if (END_OF_COMMAND) {
  707.         is_log_x = is_log_y = is_log_z = FALSE;
  708.         } else {
  709.         if (chr_in_str(c_token, 'x')) {
  710.             is_log_x = FALSE;
  711.             base_log_x = 0.0;
  712.             log_base_log_x = 0.0;
  713.                 }
  714.         if (chr_in_str(c_token, 'y')) {
  715.             is_log_y = FALSE;
  716.             base_log_y = 0.0;
  717.             log_base_log_y = 0.0;
  718.                 }
  719.         if (chr_in_str(c_token, 'z')) {
  720.             is_log_z = FALSE;
  721.             base_log_z = 0.0;
  722.             log_base_log_z = 0.0;
  723.                 }
  724.         c_token++;
  725.         }
  726.     } 
  727.     else if (almost_equals(c_token,"of$fsets")) {
  728.         c_token++;
  729.         if (END_OF_COMMAND) {
  730.             loff = roff = toff = boff = 0.0;  /* Reset offsets */
  731.         }
  732.         else {
  733.             load_offsets (&loff,&roff,&toff,&boff);
  734.         }
  735.     }
  736.     else
  737.         return(FALSE);    /* no command match */
  738.     return(TRUE);
  739. }
  740.  
  741.  
  742. /* return TRUE if a command match, FALSE if not */
  743. static TBOOLEAN
  744. set_two()
  745. {
  746.      char testfile[MAX_LINE_LEN+1];
  747. #if defined(unix) || defined(PIPES)
  748.      static TBOOLEAN pipe_open = FALSE;
  749. #endif /* unix || PIPES */
  750.  
  751.     if (almost_equals(c_token,"o$utput")) {
  752.         register FILE *f;
  753.  
  754.         c_token++;
  755.         if (term && term_init)
  756.             (*term_tbl[term].reset)();
  757.         if (END_OF_COMMAND) {    /* no file specified */
  758.              UP_redirect (4);
  759.             if (outfile != stdout) { /* Never close stdout */
  760. #if defined(unix) || defined(PIPES)
  761.                 if ( pipe_open ) {
  762.                     (void) pclose(outfile);
  763.                     pipe_open = FALSE;
  764.                 } else
  765. #endif /* unix || PIPES */
  766. #ifdef _Windows
  767.                   if ( !stricmp(outstr,"'PRN'") )
  768.                     close_printer();
  769.                   else
  770. #endif
  771.                     (void) fclose(outfile);
  772.             }
  773.             outfile = stdout; /* Don't dup... */
  774.             term_init = FALSE;
  775.             (void) strcpy(outstr,"STDOUT");
  776.         } else if (!isstring(c_token))
  777.             int_error("expecting filename",c_token);
  778.         else {
  779.             quote_str(testfile,c_token);
  780. #if defined(unix) || defined(PIPES)
  781.             if ( *testfile == '|' ) {
  782.               if ((f = popen(testfile+1,"w")) == (FILE *)NULL)
  783.                 os_error("cannot create pipe; output not changed",c_token);
  784.               else
  785.                 pipe_open = TRUE;
  786.             } else
  787. #endif /* unix || PIPES */
  788. #ifdef _Windows
  789.             if ( !stricmp(outstr,"'PRN'") ) {
  790.                 /* we can't call open_printer() while printer is open, so */
  791.                 close_printer();    /* close printer immediately if open */
  792.                 outfile = stdout;    /* and reset output to stdout */
  793.                 term_init = FALSE;
  794.                 (void) strcpy(outstr,"STDOUT");
  795.             }
  796.             if ( !stricmp(testfile,"PRN") ) {
  797.               if ((f = open_printer()) == (FILE *)NULL)
  798.                 os_error("cannot open printer temporary file; output may have changed",c_token);
  799.             } else
  800. #endif
  801.               if ((f = fopen(testfile,"w")) == (FILE *)NULL)
  802.                 os_error("cannot open file; output not changed",c_token);
  803.             if (outfile != stdout) /* Never close stdout */
  804. #if defined(unix) || defined(PIPES)
  805.                 if( pipe_open ) {
  806.                 (void) pclose(outfile);
  807.                 pipe_open=FALSE;
  808.                 } else
  809. #endif /* unix || PIPES */
  810.                 (void) fclose(outfile);
  811.             outfile = f;
  812.             term_init = FALSE;
  813.             outstr[0] = '\'';
  814.             (void) strcat(strcpy(outstr+1,testfile),"'");
  815.              UP_redirect (1);
  816.         }
  817.         c_token++;
  818.     }
  819.     else if (almost_equals(c_token,"tit$le")) {
  820.         set_xyzlabel(title,&title_xoffset,&title_yoffset);
  821.     }
  822.     else if (almost_equals(c_token,"xl$abel")) {
  823.         set_xyzlabel(xlabel,&xlabel_xoffset,&xlabel_yoffset);
  824.     }
  825.     else if (almost_equals(c_token,"yl$abel")) {
  826.         set_xyzlabel(ylabel,&ylabel_xoffset,&ylabel_yoffset);
  827.     }
  828.     else if (almost_equals(c_token,"zl$abel")) {
  829.         set_xyzlabel(zlabel,&zlabel_xoffset,&zlabel_yoffset);
  830.     }
  831.     else if (almost_equals(c_token,"xzero$axis")) {
  832.         c_token++;
  833.         xzeroaxis = TRUE;
  834.     } 
  835.     else if (almost_equals(c_token,"yzero$axis")) {
  836.         c_token++;
  837.         yzeroaxis = TRUE;
  838.     } 
  839.     else if (almost_equals(c_token,"zeroa$xis")) {
  840.         c_token++;
  841.         yzeroaxis = TRUE;
  842.         xzeroaxis = TRUE;
  843.     } 
  844.     else if (almost_equals(c_token,"noxzero$axis")) {
  845.         c_token++;
  846.         xzeroaxis = FALSE;
  847.     } 
  848.     else if (almost_equals(c_token,"noyzero$axis")) {
  849.         c_token++;
  850.         yzeroaxis = FALSE;
  851.     } 
  852.     else if (almost_equals(c_token,"nozero$axis")) {
  853.         c_token++;
  854.         xzeroaxis = FALSE;
  855.         yzeroaxis = FALSE;
  856.     } 
  857.     else if (almost_equals(c_token,"par$ametric")) {
  858.         if (!parametric) {
  859.            parametric = TRUE;
  860.            strcpy (dummy_var[0], "t");
  861.            strcpy (dummy_var[1], "y");
  862.              (void) fprintf(stderr,"\n\tdummy variable is t for curves, u/v for surfaces\n");
  863.         }
  864.         c_token++;
  865.     }
  866.     else if (almost_equals(c_token,"nopar$ametric")) {
  867.         if (parametric) {
  868.            parametric = FALSE;
  869.            strcpy (dummy_var[0], "x");
  870.            strcpy (dummy_var[1], "y");
  871.              (void) fprintf(stderr,"\n\tdummy variable is x for curves, x/y for surfaces\n");
  872.         }
  873.         c_token++;
  874.     }
  875.     else if (almost_equals(c_token,"pol$ar")) {
  876.         if (!polar) {
  877.             polar = TRUE;
  878.             if (parametric) {
  879.                 tmin = 0.0;
  880.                 tmax = 2*Pi;
  881.             } else if (angles_format == ANGLES_DEGREES) {
  882.                 xmin = 0.0;
  883.                 xmax = 360.0;
  884.             } else {
  885.                 xmin = 0.0;
  886.                 xmax = 2*Pi;
  887.             }
  888.         }
  889.         c_token++;
  890.     }
  891.     else if (almost_equals(c_token,"nopo$lar")) {
  892.         if (polar) {
  893.             polar = FALSE;
  894.             if (parametric) {
  895.                 tmin = -5.0;
  896.                 tmax = 5.0;
  897.             } else {
  898.                 xmin = -10.0;
  899.                 xmax = 10.0;
  900.             }
  901.         }
  902.         c_token++;
  903.     }
  904.     else if (almost_equals(c_token,"an$gles")) {
  905.         c_token++;
  906.         if (END_OF_COMMAND) {
  907.         /* assuming same as defaults */
  908.         angles_format = ANGLES_RADIANS;
  909.         }
  910.         else if (almost_equals(c_token, "r$adians")) {
  911.         angles_format = ANGLES_RADIANS;
  912.         c_token++;
  913.         }
  914.         else if (almost_equals(c_token, "d$egrees")) {
  915.         angles_format = ANGLES_DEGREES;
  916.         c_token++;
  917.         }
  918.         else
  919.          int_error("expecting 'radians' or 'degrees'", c_token);
  920.     }
  921.     else if (almost_equals(c_token,"g$rid")) {
  922.         grid = TRUE;
  923.         c_token++;
  924.     }
  925.     else if (almost_equals(c_token,"nog$rid")) {
  926.         grid = FALSE;
  927.         c_token++;
  928.     }
  929.     else if (almost_equals(c_token,"su$rface")) {
  930.         draw_surface = TRUE;
  931.         c_token++;
  932.     }
  933.     else if (almost_equals(c_token,"nosu$rface")) {
  934.         draw_surface = FALSE;
  935.         c_token++;
  936.     }
  937.     else if (almost_equals(c_token,"k$ey")) {
  938.         struct value a;
  939.         c_token++;
  940.         if (END_OF_COMMAND) {
  941.             key = -1;
  942.         } 
  943.         else {
  944.             key_x = real(const_express(&a));
  945.             if (!equals(c_token,","))
  946.                 int_error("',' expected",c_token);
  947.             c_token++;
  948.             key_y = real(const_express(&a));
  949.             if (equals(c_token,","))
  950.             {
  951.                     c_token++;
  952.                 key_z = real(const_express(&a));
  953.             }
  954.             key = 1;
  955.         } 
  956.     }
  957.     else if (almost_equals(c_token,"nok$ey")) {
  958.         key = 0;
  959.         c_token++;
  960.     }
  961.     else if (almost_equals(c_token,"tic$s")) {
  962.         tic_in = TRUE;
  963.         c_token++;
  964.         if (almost_equals(c_token,"i$n")) {
  965.             tic_in = TRUE;
  966.             c_token++;
  967.         }
  968.         else if (almost_equals(c_token,"o$ut")) {
  969.             tic_in = FALSE;
  970.             c_token++;
  971.         }
  972.     }
  973.      else if (almost_equals(c_token,"xmt$ics")) {
  974.      xtics = TRUE;
  975.      c_token++;
  976.      if(xticdef.type == TIC_USER){
  977.          free_marklist(xticdef.def.user);
  978.          xticdef.def.user = NULL;
  979.      }
  980.     xticdef.type = TIC_MONTH;
  981.      }
  982.      else if (almost_equals(c_token,"xdt$ics")) {
  983.      xtics = TRUE;
  984.      c_token++;
  985.      if(xticdef.type == TIC_USER){
  986.          free_marklist(xticdef.def.user);
  987.          xticdef.def.user = NULL;
  988.      }
  989.     xticdef.type = TIC_DAY;
  990.      }
  991.      else if (almost_equals(c_token,"xt$ics")) {
  992.         xtics = TRUE;
  993.         c_token++;
  994.         if (END_OF_COMMAND) { /* reset to default */
  995.            if (xticdef.type == TIC_USER) {
  996.               free_marklist(xticdef.def.user);
  997.               xticdef.def.user = NULL;
  998.            }
  999.            xticdef.type = TIC_COMPUTED;
  1000.         }
  1001.         else
  1002.          load_tics(&xticdef);
  1003.     } 
  1004.      else if (almost_equals(c_token,"noxt$ics")) {
  1005.         xtics = FALSE;
  1006.         c_token++;
  1007.     } 
  1008.      else if (almost_equals(c_token,"ymt$ics")) {
  1009.      ytics = TRUE;
  1010.      c_token++;
  1011.      if(yticdef.type == TIC_USER){
  1012.          free_marklist(yticdef.def.user);
  1013.          yticdef.def.user = NULL;
  1014.      }
  1015.     yticdef.type = TIC_MONTH;
  1016.      }
  1017.      else if (almost_equals(c_token,"ydt$ics")) {
  1018.      ytics = TRUE;
  1019.      c_token++;
  1020.      if(yticdef.type == TIC_USER){
  1021.          free_marklist(yticdef.def.user);
  1022.          yticdef.def.user = NULL;
  1023.      }
  1024.     yticdef.type = TIC_DAY;
  1025.      }
  1026.      else if (almost_equals(c_token,"yt$ics")) {
  1027.         ytics = TRUE;
  1028.         c_token++;
  1029.         if (END_OF_COMMAND) { /* reset to default */
  1030.            if (yticdef.type == TIC_USER) {
  1031.               free_marklist(yticdef.def.user);
  1032.               yticdef.def.user = NULL;
  1033.            }
  1034.            yticdef.type = TIC_COMPUTED;
  1035.         }
  1036.         else
  1037.          load_tics(&yticdef);
  1038.     } 
  1039.      else if (almost_equals(c_token,"noyt$ics")) {
  1040.         ytics = FALSE;
  1041.         c_token++;
  1042.     } 
  1043.      else if (almost_equals(c_token,"zmt$ics")) {
  1044.      ztics = TRUE;
  1045.      c_token++;
  1046.      if(zticdef.type == TIC_USER){
  1047.          free_marklist(zticdef.def.user);
  1048.          zticdef.def.user = NULL;
  1049.      }
  1050.     zticdef.type = TIC_MONTH;
  1051.      }
  1052.      else if (almost_equals(c_token,"zdt$ics")) {
  1053.      ztics = TRUE;
  1054.      c_token++;
  1055.      if(zticdef.type == TIC_USER){
  1056.          free_marklist(zticdef.def.user);
  1057.          zticdef.def.user = NULL;
  1058.      }
  1059.     zticdef.type = TIC_DAY;
  1060.      }
  1061.      else if (almost_equals(c_token,"zt$ics")) {
  1062.         ztics = TRUE;
  1063.         c_token++;
  1064.         if (END_OF_COMMAND) { /* reset to default */
  1065.            if (zticdef.type == TIC_USER) {
  1066.               free_marklist(zticdef.def.user);
  1067.               zticdef.def.user = NULL;
  1068.            }
  1069.            zticdef.type = TIC_COMPUTED;
  1070.         }
  1071.         else
  1072.          load_tics(&zticdef);
  1073.     } 
  1074.      else if (almost_equals(c_token,"nozt$ics")) {
  1075.         ztics = FALSE;
  1076.         c_token++;
  1077.     } 
  1078.     else if (almost_equals(c_token,"ticsl$evel")) {
  1079.         double tlvl;
  1080.         struct value a;
  1081.  
  1082.         c_token++;
  1083.         tlvl = real(const_express(&a));
  1084.         if (tlvl < 0.0)
  1085.             int_error("tics level must be > 0; ticslevel unchanged",
  1086.                 c_token);
  1087.         else {
  1088.             ticslevel = tlvl;
  1089.         }
  1090.     }
  1091.     else
  1092.     return(FALSE);    /* no command match */
  1093.  
  1094.     return(TRUE);
  1095. }
  1096.  
  1097.  
  1098.  
  1099. /* return TRUE if a command match, FALSE if not */
  1100. static TBOOLEAN
  1101. set_three()
  1102. {
  1103.      if (almost_equals(c_token,"sa$mples")) {
  1104.         register int tsamp1, tsamp2;
  1105.         struct value a;
  1106.  
  1107.         c_token++;
  1108.         tsamp1 = (int)magnitude(const_express(&a));
  1109.         tsamp2 = tsamp1;
  1110.         if (!END_OF_COMMAND) {
  1111.             if (!equals(c_token,","))
  1112.                 int_error("',' expected",c_token);
  1113.             c_token++;
  1114.             tsamp2 = (int)magnitude(const_express(&a));
  1115.         }
  1116.         if (tsamp1 < 2 || tsamp2 < 2)
  1117.             int_error("sampling rate must be > 1; sampling unchanged",
  1118.                 c_token);
  1119.         else {
  1120.                 extern struct surface_points *first_3dplot;
  1121.             register struct surface_points *f_3dp = first_3dplot;
  1122.  
  1123.             first_3dplot = NULL;
  1124.             sp_free(f_3dp);
  1125.  
  1126.             samples = tsamp1;
  1127.             samples_1 = tsamp1;
  1128.             samples_2 = tsamp2;
  1129.         }
  1130.     }
  1131.     else if (almost_equals(c_token,"isosa$mples")) {
  1132.         register int tsamp1, tsamp2;
  1133.         struct value a;
  1134.  
  1135.         c_token++;
  1136.         tsamp1 = (int)magnitude(const_express(&a));
  1137.         tsamp2 = tsamp1;
  1138.         if (!END_OF_COMMAND) {
  1139.             if (!equals(c_token,","))
  1140.                 int_error("',' expected",c_token);
  1141.             c_token++;
  1142.             tsamp2 = (int)magnitude(const_express(&a));
  1143.         }
  1144.         if (tsamp1 < 2 || tsamp2 < 2)
  1145.             int_error("sampling rate must be > 1; sampling unchanged",
  1146.                 c_token);
  1147.         else {
  1148.                 extern struct curve_points *first_plot;
  1149.                 extern struct surface_points *first_3dplot;
  1150.             register struct curve_points *f_p = first_plot;
  1151.             register struct surface_points *f_3dp = first_3dplot;
  1152.  
  1153.             first_plot = NULL;
  1154.             first_3dplot = NULL;
  1155.             cp_free(f_p);
  1156.             sp_free(f_3dp);
  1157.  
  1158.             iso_samples_1 = tsamp1;
  1159.             iso_samples_2 = tsamp2;
  1160.         }
  1161.     }
  1162.     else if (almost_equals(c_token,"si$ze")) {
  1163.         struct value s;
  1164.         c_token++;
  1165.         if (END_OF_COMMAND) {
  1166.             xsize = 1.0;
  1167.             ysize = 1.0;
  1168.         } 
  1169.         else {
  1170.                 xsize=real(const_express(&s));
  1171.                 if (!equals(c_token,","))
  1172.                     int_error("',' expected",c_token);
  1173.                 c_token++;
  1174.                 ysize=real(const_express(&s));
  1175.         } 
  1176.     } 
  1177.     else if (almost_equals(c_token,"t$erminal")) {
  1178.         c_token++;
  1179.         if (END_OF_COMMAND) {
  1180.             list_terms();
  1181.             screen_ok = FALSE;
  1182.         }
  1183.         else {
  1184.             if (term && term_init) {
  1185.                 (*term_tbl[term].reset)();
  1186.                 (void) fflush(outfile);
  1187.             }
  1188.             term = set_term(c_token);
  1189.             c_token++;
  1190.  
  1191.             /* get optional mode parameters */
  1192.             if (term)
  1193.                 (*term_tbl[term].options)();
  1194.             if (interactive && *term_options)
  1195.                 fprintf(stderr,"Options are '%s'\n",term_options);
  1196.         }
  1197.     }
  1198.     else if (almost_equals(c_token,"tim$e")) {
  1199.         timedate = TRUE;
  1200.         c_token++;
  1201.         if (!END_OF_COMMAND) {
  1202.             struct value a;
  1203.  
  1204.             /* We have x,y offsets specified */
  1205.             if (!equals(c_token,","))
  1206.                 time_xoffset = (int)real(const_express(&a));
  1207.             if (!END_OF_COMMAND && equals(c_token,",")) {
  1208.                 c_token++;
  1209.                 time_yoffset = (int)real(const_express(&a));
  1210.             }
  1211.         }
  1212.     }
  1213.     else if (almost_equals(c_token,"not$ime")) {
  1214.         timedate = FALSE;
  1215.         c_token++;
  1216.     }
  1217.     else if (almost_equals(c_token,"rr$ange")) {
  1218.          TBOOLEAN changed;
  1219.         c_token++;
  1220.         if (!equals(c_token,"["))
  1221.             int_error("expecting '['",c_token);
  1222.         c_token++;
  1223.         changed = load_range(&rmin,&rmax);
  1224.         if (!equals(c_token,"]"))
  1225.           int_error("expecting ']'",c_token);
  1226.         c_token++;
  1227.         if (changed)
  1228.           autoscale_r = FALSE;
  1229.     }
  1230.     else if (almost_equals(c_token,"tr$ange")) {
  1231.          TBOOLEAN changed;
  1232.         c_token++;
  1233.         if (!equals(c_token,"["))
  1234.             int_error("expecting '['",c_token);
  1235.         c_token++;
  1236.         changed = load_range(&tmin,&tmax);
  1237.         if (!equals(c_token,"]"))
  1238.           int_error("expecting ']'",c_token);
  1239.         c_token++;
  1240.         if (changed)
  1241.           autoscale_t = FALSE;
  1242.     }
  1243.     else if (almost_equals(c_token,"ur$ange")) {
  1244.          TBOOLEAN changed;
  1245.         c_token++;
  1246.         if (!equals(c_token,"["))
  1247.             int_error("expecting '['",c_token);
  1248.         c_token++;
  1249.         changed = load_range(&umin,&umax);
  1250.         if (!equals(c_token,"]"))
  1251.           int_error("expecting ']'",c_token);
  1252.         c_token++;
  1253.         if (changed)
  1254.           autoscale_u = FALSE;
  1255.     }
  1256.     else if (almost_equals(c_token,"vi$ew")) {
  1257.         int i;
  1258.         TBOOLEAN was_comma = TRUE;
  1259.         double local_vals[4];
  1260.         struct value a;
  1261.  
  1262.         local_vals[0] = surface_rot_x;
  1263.         local_vals[1] = surface_rot_z;
  1264.         local_vals[2] = surface_scale;
  1265.         local_vals[3] = surface_zscale;
  1266.         c_token++;
  1267.         for (i = 0; i < 4 && !(END_OF_COMMAND);) {
  1268.             if (equals(c_token,",")) {
  1269.                 if (was_comma) i++;
  1270.                 was_comma = TRUE;
  1271.                 c_token++;
  1272.             }
  1273.             else {
  1274.                 if (!was_comma)
  1275.                     int_error("',' expected",c_token);
  1276.                 local_vals[i] = real(const_express(&a));
  1277.                 i++;
  1278.                 was_comma = FALSE;
  1279.             }
  1280.         }
  1281.  
  1282.         if (local_vals[0] < 0 || local_vals[0] > 180)
  1283.             int_error("rot_x must be in [0:180] degrees range; view unchanged",
  1284.                   c_token);
  1285.         if (local_vals[1] < 0 || local_vals[1] > 360)
  1286.             int_error("rot_z must be in [0:360] degrees range; view unchanged",
  1287.                   c_token);
  1288.         if (local_vals[2] < 1e-6)
  1289.             int_error("scale must be > 0; view unchanged", c_token);
  1290.         if (local_vals[3] < 1e-6)
  1291.             int_error("zscale must be > 0; view unchanged", c_token);
  1292.  
  1293.         surface_rot_x = local_vals[0];
  1294.         surface_rot_z = local_vals[1];
  1295.         surface_scale = local_vals[2];
  1296.         surface_zscale = local_vals[3];
  1297.     }
  1298.     else if (almost_equals(c_token,"vr$ange")) {
  1299.          TBOOLEAN changed;
  1300.         c_token++;
  1301.         if (!equals(c_token,"["))
  1302.             int_error("expecting '['",c_token);
  1303.         c_token++;
  1304.         changed = load_range(&vmin,&vmax);
  1305.         if (!equals(c_token,"]"))
  1306.           int_error("expecting ']'",c_token);
  1307.         c_token++;
  1308.         if (changed)
  1309.           autoscale_v = FALSE;
  1310.     }
  1311.     else if (almost_equals(c_token,"xr$ange")) {
  1312.          TBOOLEAN changed;
  1313.         c_token++;
  1314.         if (!equals(c_token,"["))
  1315.             int_error("expecting '['",c_token);
  1316.         c_token++;
  1317.         changed = load_range(&xmin,&xmax);
  1318.         if (!equals(c_token,"]"))
  1319.           int_error("expecting ']'",c_token);
  1320.         c_token++;
  1321.         if (changed)
  1322.           autoscale_x = FALSE;
  1323.     }
  1324.     else if (almost_equals(c_token,"yr$ange")) {
  1325.          TBOOLEAN changed;
  1326.         c_token++;
  1327.         if (!equals(c_token,"["))
  1328.             int_error("expecting '['",c_token);
  1329.         c_token++;
  1330.         changed = load_range(&ymin,&ymax);
  1331.         if (!equals(c_token,"]"))
  1332.           int_error("expecting ']'",c_token);
  1333.         c_token++;
  1334.         if (changed)
  1335.           autoscale_y = FALSE;
  1336.     }
  1337.     else if (almost_equals(c_token,"zr$ange")) {
  1338.          TBOOLEAN changed;
  1339.         c_token++;
  1340.         if (!equals(c_token,"["))
  1341.             int_error("expecting '['",c_token);
  1342.         c_token++;
  1343.         changed = load_range(&zmin,&zmax);
  1344.         if (!equals(c_token,"]"))
  1345.           int_error("expecting ']'",c_token);
  1346.         c_token++;
  1347.         if (changed)
  1348.           autoscale_z = FALSE;
  1349.     }
  1350.     else if (almost_equals(c_token,"z$ero")) {
  1351.         struct value a;
  1352.         c_token++;
  1353.         zero = magnitude(const_express(&a));
  1354.     }
  1355.     else
  1356.         return(FALSE);    /* no command match */
  1357.     return(TRUE);
  1358. }
  1359.  
  1360. /*********** Support functions for set_command ***********/
  1361.  
  1362. /* process a 'set {x/y/z}label command */
  1363. /* set {x/y/z}label {label_text} {x}{,y} */
  1364. static void set_xyzlabel(str,xpos,ypos)
  1365. char *str;
  1366. int *xpos,*ypos;
  1367. {
  1368.     c_token++;
  1369.     if (END_OF_COMMAND) {    /* no label specified */
  1370.         str[0] = '\0';
  1371.     } else {
  1372.         if (isstring(c_token)) {
  1373.             /* We have string specified - grab it. */
  1374.             quotel_str(str,c_token);
  1375.             c_token++;
  1376.         }
  1377.         if (!END_OF_COMMAND) {
  1378.             struct value a;
  1379.  
  1380.             /* We have x,y offsets specified */
  1381.             if (!equals(c_token,","))
  1382.                 *xpos = (int)real(const_express(&a));
  1383.             if (!END_OF_COMMAND && equals(c_token,",")) {
  1384.                 c_token++;
  1385.                 *ypos = (int)real(const_express(&a));
  1386.             }
  1387.         }
  1388.     }
  1389. }
  1390.  
  1391. /* process a 'set label' command */
  1392. /* set label {tag} {label_text} {at x,y} {pos} */
  1393. static void
  1394. set_label()
  1395. {
  1396.     struct value a;
  1397.     struct text_label *this_label = NULL;
  1398.     struct text_label *new_label = NULL;
  1399.     struct text_label *prev_label = NULL;
  1400.     double x, y, z;
  1401.     char text[MAX_LINE_LEN+1];
  1402.     enum JUSTIFY just;
  1403.     int tag;
  1404.     TBOOLEAN set_text, set_position, set_just;
  1405.  
  1406.     /* get tag */
  1407.     if (!END_OF_COMMAND 
  1408.        && !isstring(c_token) 
  1409.        && !equals(c_token, "at")
  1410.        && !equals(c_token, "left")
  1411.        && !equals(c_token, "center")
  1412.        && !equals(c_token, "centre")
  1413.        && !equals(c_token, "right")) {
  1414.        /* must be a tag expression! */
  1415.        tag = (int)real(const_express(&a));
  1416.        if (tag <= 0)
  1417.         int_error("tag must be > zero", c_token);
  1418.     } else
  1419.      tag = assign_label_tag(); /* default next tag */
  1420.      
  1421.     /* get text */
  1422.     if (!END_OF_COMMAND && isstring(c_token)) {
  1423.        /* get text */
  1424.        quotel_str(text, c_token);
  1425.        c_token++;
  1426.        set_text = TRUE;
  1427.     } else {
  1428.        text[0] = '\0';        /* default no text */
  1429.        set_text = FALSE;
  1430.     }
  1431.      
  1432.     /* get justification - what the heck, let him put it here */
  1433.     if (!END_OF_COMMAND && !equals(c_token, "at")) {
  1434.        if (almost_equals(c_token,"l$eft")) {
  1435.           just = LEFT;
  1436.        }
  1437.        else if (almost_equals(c_token,"c$entre")
  1438.               || almost_equals(c_token,"c$enter")) {
  1439.           just = CENTRE;
  1440.        }
  1441.        else if (almost_equals(c_token,"r$ight")) {
  1442.           just = RIGHT;
  1443.        }
  1444.        else
  1445.         int_error("bad syntax in set label", c_token);
  1446.        c_token++;
  1447.        set_just = TRUE;
  1448.     } else {
  1449.        just = LEFT;            /* default left justified */
  1450.        set_just = FALSE;
  1451.     } 
  1452.  
  1453.     /* get position */
  1454.     if (!END_OF_COMMAND && equals(c_token, "at")) {
  1455.        c_token++;
  1456.        if (END_OF_COMMAND)
  1457.         int_error("coordinates expected", c_token);
  1458.        /* get coordinates */
  1459.        x = real(const_express(&a));
  1460.        if (!equals(c_token,","))
  1461.         int_error("',' expected",c_token);
  1462.        c_token++;
  1463.        y = real(const_express(&a));
  1464.        if (equals(c_token,",")) {
  1465.         c_token++;
  1466.         z = real(const_express(&a));
  1467.        }
  1468.        else
  1469.             z = 0;
  1470.        set_position = TRUE;
  1471.     } else {
  1472.        x = y = z = 0;            /* default at origin */
  1473.        set_position = FALSE;
  1474.     }
  1475.  
  1476.     /* get justification */
  1477.     if (!END_OF_COMMAND) {
  1478.        if (set_just)
  1479.         int_error("only one justification is allowed", c_token);
  1480.        if (almost_equals(c_token,"l$eft")) {
  1481.           just = LEFT;
  1482.        }
  1483.        else if (almost_equals(c_token,"c$entre")
  1484.               || almost_equals(c_token,"c$enter")) {
  1485.           just = CENTRE;
  1486.        }
  1487.        else if (almost_equals(c_token,"r$ight")) {
  1488.           just = RIGHT;
  1489.        }
  1490.        else
  1491.         int_error("bad syntax in set label", c_token);
  1492.        c_token++;
  1493.        set_just = TRUE;
  1494.     } 
  1495.  
  1496.     if (!END_OF_COMMAND)
  1497.      int_error("extraenous or out-of-order arguments in set label", c_token);
  1498.  
  1499.     /* OK! add label */
  1500.     if (first_label != NULL) { /* skip to last label */
  1501.        for (this_label = first_label; this_label != NULL ; 
  1502.            prev_label = this_label, this_label = this_label->next)
  1503.         /* is this the label we want? */
  1504.         if (tag <= this_label->tag)
  1505.           break;
  1506.     }
  1507.     if (this_label != NULL && tag == this_label->tag) {
  1508.        /* changing the label */
  1509.        if (set_position) {
  1510.           this_label->x = x;
  1511.           this_label->y = y;
  1512.           this_label->z = z;
  1513.        }
  1514.        if (set_text)
  1515.         (void) strcpy(this_label->text, text);
  1516.        if (set_just)
  1517.         this_label->pos = just;
  1518.     } else {
  1519.        /* adding the label */
  1520.        new_label = (struct text_label *) 
  1521.         alloc ( (unsigned long) sizeof(struct text_label), "label");
  1522.        if (prev_label != NULL)
  1523.         prev_label->next = new_label; /* add it to end of list */
  1524.        else 
  1525.         first_label = new_label; /* make it start of list */
  1526.        new_label->tag = tag;
  1527.        new_label->next = this_label;
  1528.        new_label->x = x;
  1529.        new_label->y = y;
  1530.        new_label->z = z;
  1531.        (void) strcpy(new_label->text, text);
  1532.        new_label->pos = just;
  1533.     }
  1534. }
  1535.  
  1536. /* process 'set nolabel' command */
  1537. /* set nolabel {tag} */
  1538. static void
  1539. set_nolabel()
  1540. {
  1541.     struct value a;
  1542.     struct text_label *this_label;
  1543.     struct text_label *prev_label; 
  1544.     int tag;
  1545.  
  1546.     if (END_OF_COMMAND) {
  1547.        /* delete all labels */
  1548.        while (first_label != NULL)
  1549.         delete_label((struct text_label *)NULL,first_label);
  1550.     }
  1551.     else {
  1552.        /* get tag */
  1553.        tag = (int)real(const_express(&a));
  1554.        if (!END_OF_COMMAND)
  1555.         int_error("extraneous arguments to set nolabel", c_token);
  1556.        for (this_label = first_label, prev_label = NULL;
  1557.            this_label != NULL;
  1558.            prev_label = this_label, this_label = this_label->next) {
  1559.           if (this_label->tag == tag) {
  1560.              delete_label(prev_label,this_label);
  1561.              return;        /* exit, our job is done */
  1562.           }
  1563.        }
  1564.        int_error("label not found", c_token);
  1565.     }
  1566. }
  1567.  
  1568. /* assign a new label tag */
  1569. /* labels are kept sorted by tag number, so this is easy */
  1570. static int                /* the lowest unassigned tag number */
  1571. assign_label_tag()
  1572. {
  1573.     struct text_label *this_label;
  1574.     int last = 0;            /* previous tag value */
  1575.  
  1576.     for (this_label = first_label; this_label != NULL;
  1577.         this_label = this_label->next)
  1578.      if (this_label->tag == last+1)
  1579.        last++;
  1580.      else
  1581.        break;
  1582.     
  1583.     return (last+1);
  1584. }
  1585.  
  1586. /* delete label from linked list started by first_label.
  1587.  * called with pointers to the previous label (prev) and the 
  1588.  * label to delete (this).
  1589.  * If there is no previous label (the label to delete is
  1590.  * first_label) then call with prev = NULL.
  1591.  */
  1592. static void
  1593. delete_label(prev,this)
  1594.     struct text_label *prev, *this;
  1595. {
  1596.     if (this!=NULL)    {        /* there really is something to delete */
  1597.        if (prev!=NULL)        /* there is a previous label */
  1598.         prev->next = this->next; 
  1599.        else                /* this = first_label so change first_label */
  1600.         first_label = this->next;
  1601.        free((char *)this);
  1602.     }
  1603. }
  1604.  
  1605.  
  1606. /* process a 'set arrow' command */
  1607. /* set arrow {tag} {from x,y} {to x,y} {{no}head} */
  1608. static void
  1609. set_arrow()
  1610. {
  1611.     struct value a;
  1612.     struct arrow_def *this_arrow = NULL;
  1613.     struct arrow_def *new_arrow = NULL;
  1614.     struct arrow_def *prev_arrow = NULL;
  1615.     double sx, sy, sz;
  1616.     double ex, ey, ez;
  1617.     int tag;
  1618.     TBOOLEAN set_start, set_end, head = 1;
  1619.  
  1620.     /* get tag */
  1621.     if (!END_OF_COMMAND 
  1622.        && !equals(c_token, "from")
  1623.        && !equals(c_token, "to")) {
  1624.        /* must be a tag expression! */
  1625.        tag = (int)real(const_express(&a));
  1626.        if (tag <= 0)
  1627.         int_error("tag must be > zero", c_token);
  1628.     } else
  1629.      tag = assign_arrow_tag(); /* default next tag */
  1630.      
  1631.     /* get start position */
  1632.     if (!END_OF_COMMAND && equals(c_token, "from")) {
  1633.        c_token++;
  1634.        if (END_OF_COMMAND)
  1635.         int_error("start coordinates expected", c_token);
  1636.        /* get coordinates */
  1637.        sx = real(const_express(&a));
  1638.        if (!equals(c_token,","))
  1639.         int_error("',' expected",c_token);
  1640.        c_token++;
  1641.        sy = real(const_express(&a));
  1642.        if (equals(c_token,",")) {
  1643.         c_token++;
  1644.         sz = real(const_express(&a));
  1645.        }
  1646.        else
  1647.            sz = 0;
  1648.        set_start = TRUE;
  1649.     } else {
  1650.        sx = sy = sz = 0;            /* default at origin */
  1651.        set_start = FALSE;
  1652.     }
  1653.  
  1654.     /* get end position */
  1655.     if (!END_OF_COMMAND && equals(c_token, "to")) {
  1656.        c_token++;
  1657.        if (END_OF_COMMAND)
  1658.         int_error("end coordinates expected", c_token);
  1659.        /* get coordinates */
  1660.        ex = real(const_express(&a));
  1661.        if (!equals(c_token,","))
  1662.         int_error("',' expected",c_token);
  1663.        c_token++;
  1664.        ey = real(const_express(&a));
  1665.        if (equals(c_token,",")) {
  1666.         c_token++;
  1667.         ez = real(const_express(&a));
  1668.        }
  1669.        else
  1670.         ez = 0;
  1671.        set_end = TRUE;
  1672.     } else {
  1673.        ex = ey = ez = 0;            /* default at origin */
  1674.        set_end = FALSE;
  1675.     }
  1676.  
  1677.     /* get start position - what the heck, either order is ok */
  1678.     if (!END_OF_COMMAND && equals(c_token, "from")) {
  1679.        if (set_start)
  1680.         int_error("only one 'from' is allowed", c_token);
  1681.        c_token++;
  1682.        if (END_OF_COMMAND)
  1683.         int_error("start coordinates expected", c_token);
  1684.        /* get coordinates */
  1685.        sx = real(const_express(&a));
  1686.        if (!equals(c_token,","))
  1687.         int_error("',' expected",c_token);
  1688.        c_token++;
  1689.        sy = real(const_express(&a));
  1690.        if (equals(c_token,",")) {
  1691.         c_token++;
  1692.         sz = real(const_express(&a));
  1693.        }
  1694.        else
  1695.            sz = 0;
  1696.        set_start = TRUE;
  1697.     }
  1698.  
  1699.     if (!END_OF_COMMAND && equals(c_token, "nohead")) {
  1700.        c_token++;
  1701.            head = 0;
  1702.     }
  1703.  
  1704.     if (!END_OF_COMMAND && equals(c_token, "head")) {
  1705.        c_token++;
  1706.            head = 1;
  1707.     }
  1708.  
  1709.     if (!END_OF_COMMAND)
  1710.      int_error("extraneous or out-of-order arguments in set arrow", c_token);
  1711.  
  1712.     /* OK! add arrow */
  1713.     if (first_arrow != NULL) { /* skip to last arrow */
  1714.        for (this_arrow = first_arrow; this_arrow != NULL ; 
  1715.            prev_arrow = this_arrow, this_arrow = this_arrow->next)
  1716.         /* is this the arrow we want? */
  1717.         if (tag <= this_arrow->tag)
  1718.           break;
  1719.     }
  1720.     if (this_arrow != NULL && tag == this_arrow->tag) {
  1721.        /* changing the arrow */
  1722.        if (set_start) {
  1723.           this_arrow->sx = sx;
  1724.           this_arrow->sy = sy;
  1725.           this_arrow->sz = sz;
  1726.        }
  1727.        if (set_end) {
  1728.           this_arrow->ex = ex;
  1729.           this_arrow->ey = ey;
  1730.           this_arrow->ez = ez;
  1731.        }
  1732.        this_arrow->head = head;
  1733.     } else {
  1734.        /* adding the arrow */
  1735.        new_arrow = (struct arrow_def *) 
  1736.         alloc ( (unsigned long) sizeof(struct arrow_def), "arrow");
  1737.        if (prev_arrow != NULL)
  1738.         prev_arrow->next = new_arrow; /* add it to end of list */
  1739.        else 
  1740.         first_arrow = new_arrow; /* make it start of list */
  1741.        new_arrow->tag = tag;
  1742.        new_arrow->next = this_arrow;
  1743.        new_arrow->sx = sx;
  1744.        new_arrow->sy = sy;
  1745.        new_arrow->sz = sz;
  1746.        new_arrow->ex = ex;
  1747.        new_arrow->ey = ey;
  1748.        new_arrow->ez = ez;
  1749.        new_arrow->head = head;
  1750.     }
  1751. }
  1752.  
  1753. /* process 'set noarrow' command */
  1754. /* set noarrow {tag} */
  1755. static void
  1756. set_noarrow()
  1757. {
  1758.     struct value a;
  1759.     struct arrow_def *this_arrow;
  1760.     struct arrow_def *prev_arrow; 
  1761.     int tag;
  1762.  
  1763.     if (END_OF_COMMAND) {
  1764.        /* delete all arrows */
  1765.        while (first_arrow != NULL)
  1766.         delete_arrow((struct arrow_def *)NULL,first_arrow);
  1767.     }
  1768.     else {
  1769.        /* get tag */
  1770.        tag = (int)real(const_express(&a));
  1771.        if (!END_OF_COMMAND)
  1772.         int_error("extraneous arguments to set noarrow", c_token);
  1773.        for (this_arrow = first_arrow, prev_arrow = NULL;
  1774.            this_arrow != NULL;
  1775.            prev_arrow = this_arrow, this_arrow = this_arrow->next) {
  1776.           if (this_arrow->tag == tag) {
  1777.              delete_arrow(prev_arrow,this_arrow);
  1778.              return;        /* exit, our job is done */
  1779.           }
  1780.        }
  1781.        int_error("arrow not found", c_token);
  1782.     }
  1783. }
  1784.  
  1785. /* assign a new arrow tag */
  1786. /* arrows are kept sorted by tag number, so this is easy */
  1787. static int                /* the lowest unassigned tag number */
  1788. assign_arrow_tag()
  1789. {
  1790.     struct arrow_def *this_arrow;
  1791.     int last = 0;            /* previous tag value */
  1792.  
  1793.     for (this_arrow = first_arrow; this_arrow != NULL;
  1794.         this_arrow = this_arrow->next)
  1795.      if (this_arrow->tag == last+1)
  1796.        last++;
  1797.      else
  1798.        break;
  1799.  
  1800.     return (last+1);
  1801. }
  1802.  
  1803. /* delete arrow from linked list started by first_arrow.
  1804.  * called with pointers to the previous arrow (prev) and the 
  1805.  * arrow to delete (this).
  1806.  * If there is no previous arrow (the arrow to delete is
  1807.  * first_arrow) then call with prev = NULL.
  1808.  */
  1809. static void
  1810. delete_arrow(prev,this)
  1811.     struct arrow_def *prev, *this;
  1812. {
  1813.     if (this!=NULL)    {        /* there really is something to delete */
  1814.        if (prev!=NULL)        /* there is a previous arrow */
  1815.         prev->next = this->next; 
  1816.        else                /* this = first_arrow so change first_arrow */
  1817.         first_arrow = this->next;
  1818.        free((char *)this);
  1819.     }
  1820. }
  1821.  
  1822.  
  1823. enum PLOT_STYLE            /* not static; used by command.c */
  1824. get_style()
  1825. {
  1826. register enum PLOT_STYLE ps;
  1827.  
  1828.     c_token++;
  1829.     if (almost_equals(c_token,"l$ines"))
  1830.         ps = LINES;
  1831.     else if (almost_equals(c_token,"i$mpulses"))
  1832.         ps = IMPULSES;
  1833.     else if (almost_equals(c_token,"p$oints"))
  1834.         ps = POINTSTYLE;
  1835.     else if (almost_equals(c_token,"linesp$oints"))
  1836.         ps = LINESPOINTS;
  1837.     else if (almost_equals(c_token,"d$ots"))
  1838.         ps = DOTS;
  1839.     else if (almost_equals(c_token,"e$rrorbars"))
  1840.         ps = ERRORBARS;
  1841.     else if (almost_equals(c_token,"b$oxes"))
  1842.         ps = BOXES;
  1843.     else if (almost_equals(c_token,"boxer$rorbars"))
  1844.         ps = BOXERROR;
  1845.     else if (almost_equals(c_token,"s$teps"))
  1846.         ps = STEPS;
  1847.     else
  1848.         int_error("expecting 'lines', 'points', 'linespoints', 'dots', 'impulses', \n\
  1849.         'errorbars', 'steps', 'boxes' or 'boxerrorbars'",c_token);
  1850.     c_token++;
  1851.     return(ps);
  1852. }
  1853.  
  1854. /* For set [xy]tics... command*/
  1855. static void
  1856. load_tics(tdef)
  1857.     struct ticdef *tdef;    /* change this ticdef */
  1858. {
  1859.     if (equals(c_token,"(")) { /* set : TIC_USER */
  1860.        c_token++;
  1861.        load_tic_user(tdef);
  1862.     } else {                /* series : TIC_SERIES */
  1863.        load_tic_series(tdef);
  1864.     }
  1865. }
  1866.  
  1867. /* load TIC_USER definition */
  1868. /* (tic[,tic]...)
  1869.  * where tic is ["string"] value
  1870.  * Left paren is already scanned off before entry.
  1871.  */
  1872. static void
  1873. load_tic_user(tdef)
  1874.     struct ticdef *tdef;
  1875. {
  1876.     struct ticmark *list = NULL; /* start of list */
  1877.     struct ticmark *last = NULL; /* end of list */
  1878.     struct ticmark *tic = NULL; /* new ticmark */
  1879.     char temp_string[MAX_LINE_LEN];
  1880.     struct value a;
  1881.  
  1882.     while (!END_OF_COMMAND) {
  1883.        /* parse a new ticmark */
  1884.        tic = (struct ticmark *)alloc((unsigned long)sizeof(struct ticmark), (char *)NULL);
  1885.        if (tic == (struct ticmark *)NULL) {
  1886.           free_marklist(list);
  1887.           int_error("out of memory for tic mark", c_token);
  1888.        }
  1889.  
  1890.        /* has a string with it? */
  1891.        if (isstring(c_token)) {
  1892.           quote_str(temp_string,c_token);
  1893.           tic->label = alloc((unsigned long)strlen(temp_string)+1, "tic label");
  1894.           (void) strcpy(tic->label, temp_string);
  1895.           c_token++;
  1896.        } else
  1897.         tic->label = NULL;
  1898.  
  1899.        /* in any case get the value */
  1900.        tic->position = real(const_express(&a));
  1901.        tic->next = NULL;
  1902.  
  1903.        /* append to list */
  1904.        if (list == NULL)
  1905.         last = list = tic;    /* new list */
  1906.        else {                /* append to list */
  1907.           last->next = tic;
  1908.           last = tic;
  1909.        }
  1910.  
  1911.        /* expect "," or ")" here */
  1912.        if (!END_OF_COMMAND && equals(c_token, ","))
  1913.         c_token++;        /* loop again */
  1914.        else
  1915.         break;            /* hopefully ")" */
  1916.     }
  1917.     
  1918.     if (END_OF_COMMAND || !equals(c_token, ")")) {
  1919.        free_marklist(list);
  1920.        int_error("expecting right parenthesis )", c_token);
  1921.     }
  1922.     c_token++;
  1923.     
  1924.     /* successful list */
  1925.     if (tdef->type == TIC_USER) {
  1926.        /* remove old list */
  1927.         /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  1928.        free_marklist(tdef->def.user);
  1929.        tdef->def.user = NULL;
  1930.     }
  1931.     tdef->type = TIC_USER;
  1932.     tdef->def.user = list;
  1933. }
  1934.  
  1935. static void
  1936. free_marklist(list)
  1937.     struct ticmark *list;
  1938. {
  1939.     register struct ticmark *freeable;
  1940.  
  1941.     while (list != NULL) {
  1942.        freeable = list;
  1943.        list = list->next;
  1944.        if (freeable->label != NULL)
  1945.         free( (char *)freeable->label );
  1946.        free( (char *)freeable );
  1947.     }
  1948. }
  1949.  
  1950. /* load TIC_SERIES definition */
  1951. /* start,incr[,end] */
  1952. static void
  1953. load_tic_series(tdef)
  1954.     struct ticdef *tdef;
  1955. {
  1956.     double start, incr, end;
  1957.     struct value a;
  1958.     int incr_token;
  1959.  
  1960.     start = real(const_express(&a));
  1961.     if (!equals(c_token, ","))
  1962.      int_error("expecting comma to separate start,incr", c_token);
  1963.     c_token++;
  1964.  
  1965.     incr_token = c_token;
  1966.     incr = real(const_express(&a));
  1967.  
  1968.     if (END_OF_COMMAND)
  1969.      end = VERYLARGE;
  1970.     else {
  1971.        if (!equals(c_token, ","))
  1972.         int_error("expecting comma to separate incr,end", c_token);
  1973.        c_token++;
  1974.  
  1975.        end = real(const_express(&a));
  1976.     }
  1977.     if (!END_OF_COMMAND)
  1978.      int_error("tic series is defined by start,increment[,end]", 
  1979.              c_token);
  1980.     
  1981.     if (start < end && incr <= 0)
  1982.      int_error("increment must be positive", incr_token);
  1983.     if (start > end && incr >= 0)
  1984.      int_error("increment must be negative", incr_token);
  1985.     if (start > end) {
  1986.        /* put in order */
  1987.         double numtics;
  1988.         numtics = floor( (end*(1+SIGNIF) - start)/incr );
  1989.         end = start;
  1990.         start = end + numtics*incr;
  1991.         incr = -incr;
  1992. /*
  1993.        double temp = start;
  1994.        start = end;
  1995.        end = temp;
  1996.        incr = -incr;
  1997.  */
  1998.     }
  1999.  
  2000.     if (tdef->type == TIC_USER) {
  2001.        /* remove old list */
  2002.         /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  2003.        free_marklist(tdef->def.user);
  2004.        tdef->def.user = NULL;
  2005.     }
  2006.     tdef->type = TIC_SERIES;
  2007.     tdef->def.series.start = start;
  2008.     tdef->def.series.incr = incr;
  2009.     tdef->def.series.end = end;
  2010. }
  2011.  
  2012. static void
  2013. load_offsets (a, b, c, d)
  2014. double *a,*b, *c, *d;
  2015. {
  2016. struct value t;
  2017.  
  2018.     *a = real (const_express(&t));  /* loff value */
  2019.     c_token++;
  2020.     if (equals(c_token,","))
  2021.         c_token++;
  2022.     if (END_OF_COMMAND) 
  2023.         return;
  2024.  
  2025.     *b = real (const_express(&t));  /* roff value */
  2026.     c_token++;
  2027.     if (equals(c_token,","))
  2028.         c_token++;
  2029.     if (END_OF_COMMAND) 
  2030.         return;
  2031.  
  2032.     *c = real (const_express(&t));  /* toff value */
  2033.     c_token++;
  2034.     if (equals(c_token,","))
  2035.         c_token++;
  2036.     if (END_OF_COMMAND) 
  2037.         return;
  2038.  
  2039.     *d = real (const_express(&t));  /* boff value */
  2040.     c_token++;
  2041. }
  2042.  
  2043.  
  2044. TBOOLEAN                    /* TRUE if a or b were changed */
  2045. load_range(a,b)            /* also used by command.c */
  2046. double *a,*b;
  2047. {
  2048. struct value t;
  2049. TBOOLEAN changed = FALSE;
  2050.  
  2051.     if (equals(c_token,"]"))
  2052.         return(FALSE);
  2053.     if (END_OF_COMMAND) {
  2054.         int_error("starting range value or ':' or 'to' expected",c_token);
  2055.     } else if (!equals(c_token,"to") && !equals(c_token,":"))  {
  2056.         *a = real(const_express(&t));
  2057.         changed = TRUE;
  2058.     }    
  2059.     if (!equals(c_token,"to") && !equals(c_token,":"))
  2060.         int_error("':' or keyword 'to' expected",c_token);
  2061.     c_token++;
  2062.     if (!equals(c_token,"]")) {
  2063.         *b = real(const_express(&t));
  2064.         changed = TRUE;
  2065.      }
  2066.      return(changed);
  2067. }
  2068.  
  2069.  
  2070.  
  2071. /******* The 'show' command *******/
  2072. void
  2073. show_command()
  2074. {
  2075.     c_token++;
  2076.  
  2077.     if (!show_one() && !show_two())
  2078.     int_error(
  2079.     "valid show options:  'action_table', 'all', 'angles', 'arrow', \n\
  2080.     'autoscale', 'border', 'boxwidth', 'clip', 'contour', 'data', \n\
  2081.     'dgrid3d', 'dummy', 'format', 'function', 'grid', 'hidden', 'key', \n\
  2082.     'label', 'logscale', 'mapping',  'offsets', 'output', 'plot', \n\
  2083.     'parametric', 'polar', 'rrange', 'samples', 'isosamples', 'view', \n\
  2084.     'size', 'terminal', 'tics', 'ticslevel', 'time', 'title', 'trange', \n\
  2085.     'urange', 'vrange', 'variables', 'version', \n\
  2086.     'xlabel', 'xrange', '{no}xtics', 'xmtics', 'xdtics', '{no}xzeroaxis',\n\
  2087.     'ylabel', 'yrange', '{no}ytics', 'ymtics', 'ydtics', '{no}yzeroaxis',\n\
  2088.      'zero', '{no}zeroaxis', 'zlabel', 'zrange', '{no}ztics',\n\
  2089.      'zmtics', 'zdtics'", c_token);
  2090.     screen_ok = FALSE;
  2091.     (void) putc('\n',stderr);
  2092. }
  2093.  
  2094. /* return TRUE if a command match, FALSE if not */
  2095. static TBOOLEAN
  2096. show_one()
  2097. {
  2098.     if (almost_equals(c_token,"ac$tion_table") ||
  2099.              equals(c_token,"at") ) {
  2100.         c_token++; 
  2101.         show_at();
  2102.         c_token++;
  2103.     }
  2104.     else if (almost_equals(c_token,"ar$row")) {
  2105.         struct value a;
  2106.         int tag = 0;
  2107.  
  2108.         c_token++;
  2109.         if (!END_OF_COMMAND) {
  2110.            tag = (int)real(const_express(&a));
  2111.            if (tag <= 0)
  2112.             int_error("tag must be > zero", c_token);
  2113.         }
  2114.  
  2115.         (void) putc('\n',stderr);
  2116.         show_arrow(tag);
  2117.     }
  2118.     else if (almost_equals(c_token,"au$toscale")) {
  2119.         (void) putc('\n',stderr);
  2120.         show_autoscale();
  2121.         c_token++;
  2122.     }
  2123.     else if (almost_equals(c_token,"bor$der")) {
  2124.         (void) putc('\n',stderr);
  2125.         show_border();
  2126.         c_token++;
  2127.     }
  2128.     else if (almost_equals(c_token,"box$width")) {
  2129.         (void) putc('\n',stderr);
  2130.         show_boxwidth();
  2131.         c_token++;
  2132.     }
  2133.     else if (almost_equals(c_token,"c$lip")) {
  2134.         (void) putc('\n',stderr);
  2135.         show_clip();
  2136.         c_token++;
  2137.     }
  2138.     else if (almost_equals(c_token,"ma$pping")) {
  2139.         (void) putc('\n',stderr);
  2140.         show_mapping();
  2141.         c_token++;
  2142.     }
  2143.     else if (almost_equals(c_token,"co$ntour")) {
  2144.         (void) putc('\n',stderr);
  2145.         show_contour();
  2146.         c_token++;
  2147.     }
  2148.     else if (almost_equals(c_token,"da$ta")) {
  2149.         c_token++;
  2150.         if (!almost_equals(c_token,"s$tyle"))
  2151.             int_error("expecting keyword 'style'",c_token);
  2152.         (void) putc('\n',stderr);
  2153.         show_style("data",data_style);
  2154.         c_token++;
  2155.     }
  2156.     else if (almost_equals(c_token,"dg$rid3d")) {
  2157.         (void) putc('\n',stderr);
  2158.         show_dgrid3d();
  2159.         c_token++;
  2160.     }
  2161.     else if (almost_equals(c_token,"du$mmy")) {
  2162.           (void) fprintf(stderr,"\n\tdummy variables are \"%s\" and \"%s\"\n",
  2163.                         dummy_var[0], dummy_var[1]);
  2164.         c_token++;
  2165.     }
  2166.     else if (almost_equals(c_token,"fo$rmat")) {
  2167.         show_format();
  2168.         c_token++;
  2169.     }
  2170.     else if (almost_equals(c_token,"fu$nctions")) {
  2171.         c_token++;
  2172.         if (almost_equals(c_token,"s$tyle"))  {
  2173.             (void) putc('\n',stderr);
  2174.             show_style("functions",func_style);
  2175.             c_token++;
  2176.         }
  2177.         else
  2178.             show_functions();
  2179.     }
  2180.     else if (almost_equals(c_token,"lo$gscale")) {
  2181.         (void) putc('\n',stderr);
  2182.         show_logscale();
  2183.         c_token++;
  2184.     }
  2185.     else if (almost_equals(c_token,"of$fsets")) {
  2186.         (void) putc('\n',stderr);
  2187.         show_offsets();
  2188.         c_token++;
  2189.     }
  2190.     else if (almost_equals(c_token,"o$utput")) {
  2191.         (void) putc('\n',stderr);
  2192.         show_output();
  2193.         c_token++;
  2194.     }
  2195.     else if (almost_equals(c_token,"tit$le")) {
  2196.         (void) putc('\n',stderr);
  2197.         show_title();
  2198.         c_token++;
  2199.     }
  2200.     else if (almost_equals(c_token,"xl$abel")) {
  2201.         (void) putc('\n',stderr);
  2202.         show_xlabel();
  2203.         c_token++;
  2204.     }
  2205.     else if (almost_equals(c_token,"yl$abel")) {
  2206.         (void) putc('\n',stderr);
  2207.         show_ylabel();
  2208.         c_token++;
  2209.     }
  2210.     else if (almost_equals(c_token,"zl$abel")) {
  2211.         (void) putc('\n',stderr);
  2212.         show_zlabel();
  2213.         c_token++;
  2214.     }
  2215.     else if (almost_equals(c_token,"xzero$axis")) {
  2216.         (void) putc('\n',stderr);
  2217.         show_xzeroaxis();
  2218.         c_token++;
  2219.     }
  2220.     else if (almost_equals(c_token,"yzero$axis")) {
  2221.         (void) putc('\n',stderr);
  2222.         show_yzeroaxis();
  2223.         c_token++;
  2224.     }
  2225.     else if (almost_equals(c_token,"zeroa$xis")) {
  2226.         (void) putc('\n',stderr);
  2227.         show_xzeroaxis();
  2228.         show_yzeroaxis();
  2229.         c_token++;
  2230.     }
  2231.     else if (almost_equals(c_token,"la$bel")) {
  2232.         struct value a;
  2233.         int tag = 0;
  2234.  
  2235.         c_token++;
  2236.         if (!END_OF_COMMAND) {
  2237.            tag = (int)real(const_express(&a));
  2238.            if (tag <= 0)
  2239.             int_error("tag must be > zero", c_token);
  2240.         }
  2241.  
  2242.         (void) putc('\n',stderr);
  2243.         show_label(tag);
  2244.     }
  2245.     else if (almost_equals(c_token,"g$rid")) {
  2246.         (void) putc('\n',stderr);
  2247.         show_grid();
  2248.         c_token++;
  2249.     }
  2250.     else if (almost_equals(c_token,"k$ey")) {
  2251.         (void) putc('\n',stderr);
  2252.         show_key();
  2253.         c_token++;
  2254.     }
  2255.     else
  2256.         return (FALSE);
  2257.     return TRUE;
  2258. }
  2259.  
  2260. /* return TRUE if a command match, FALSE if not */
  2261. static TBOOLEAN
  2262. show_two()
  2263. {
  2264.     if (almost_equals(c_token,"p$lot")) {
  2265.         (void) putc('\n',stderr);
  2266.         show_plot();
  2267.         c_token++;
  2268.     }
  2269.     else if (almost_equals(c_token,"par$ametric")) {
  2270.         (void) putc('\n',stderr);
  2271.         show_parametric();
  2272.         c_token++;
  2273.     }
  2274.     else if (almost_equals(c_token,"pol$ar")) {
  2275.         (void) putc('\n',stderr);
  2276.         show_polar();
  2277.         c_token++;
  2278.     }
  2279.     else if (almost_equals(c_token,"an$gles")) {
  2280.         (void) putc('\n',stderr);
  2281.         show_angles();
  2282.         c_token++;
  2283.     }
  2284.     else if (almost_equals(c_token,"ti$cs")) {
  2285.         (void) putc('\n',stderr);
  2286.         show_tics(TRUE,TRUE,TRUE);
  2287.         c_token++;
  2288.     }
  2289.     else if (almost_equals(c_token,"tim$e")) {
  2290.         (void) putc('\n',stderr);
  2291.         show_time();
  2292.         c_token++;
  2293.     }
  2294.     else if (almost_equals(c_token,"su$rface")) {
  2295.         (void) putc('\n',stderr);
  2296.         show_surface();
  2297.         c_token++;
  2298.     }
  2299.     else if (almost_equals(c_token,"hi$dden3d")) {
  2300.         (void) putc('\n',stderr);
  2301.         show_hidden3d();
  2302.         c_token++;
  2303.     }
  2304.      else if (almost_equals(c_token,"cla$bel")) {
  2305.          (void) putc('\n',stderr);
  2306.          show_label_contours();
  2307.          c_token++;
  2308.      }
  2309.     else if (almost_equals(c_token,"xti$cs")) {
  2310.         show_tics(TRUE,FALSE,FALSE);
  2311.         c_token++;
  2312.     }
  2313.     else if (almost_equals(c_token,"yti$cs")) {
  2314.         show_tics(FALSE,TRUE,FALSE);
  2315.         c_token++;
  2316.     }
  2317.     else if (almost_equals(c_token,"zti$cs")) {
  2318.         show_tics(FALSE,FALSE,TRUE);
  2319.         c_token++;
  2320.     }
  2321.     else if (almost_equals(c_token,"sa$mples")) {
  2322.         (void) putc('\n',stderr);
  2323.         show_samples();
  2324.         c_token++;
  2325.     }
  2326.     else if (almost_equals(c_token,"isosa$mples")) {
  2327.         (void) putc('\n',stderr);
  2328.         show_isosamples();
  2329.         c_token++;
  2330.     }
  2331.     else if (almost_equals(c_token,"si$ze")) {
  2332.         (void) putc('\n',stderr);
  2333.         show_size();
  2334.         c_token++;
  2335.     }
  2336.     else if (almost_equals(c_token,"t$erminal")) {
  2337.         (void) putc('\n',stderr);
  2338.         show_term();
  2339.         c_token++;
  2340.     }
  2341.     else if (almost_equals(c_token,"rr$ange")) {
  2342.         (void) putc('\n',stderr);
  2343.         show_range('r',rmin,rmax);
  2344.         c_token++;
  2345.     }
  2346.     else if (almost_equals(c_token,"tr$ange")) {
  2347.         (void) putc('\n',stderr);
  2348.         show_range('t',tmin,tmax);
  2349.         c_token++;
  2350.     }
  2351.     else if (almost_equals(c_token,"ur$ange")) {
  2352.         (void) putc('\n',stderr);
  2353.         show_range('u',umin,umax);
  2354.         c_token++;
  2355.     }
  2356.     else if (almost_equals(c_token,"vi$ew")) {
  2357.         (void) putc('\n',stderr);
  2358.         show_view();
  2359.         c_token++;
  2360.     }
  2361.     else if (almost_equals(c_token,"vr$ange")) {
  2362.         (void) putc('\n',stderr);
  2363.         show_range('v',vmin,vmax);
  2364.         c_token++;
  2365.     }
  2366.     else if (almost_equals(c_token,"v$ariables")) {
  2367.         show_variables();
  2368.         c_token++;
  2369.     }
  2370.     else if (almost_equals(c_token,"ve$rsion")) {
  2371.         show_version();
  2372.         c_token++;
  2373.     }
  2374.     else if (almost_equals(c_token,"xr$ange")) {
  2375.         (void) putc('\n',stderr);
  2376.         show_range('x',xmin,xmax);
  2377.         c_token++;
  2378.     }
  2379.     else if (almost_equals(c_token,"yr$ange")) {
  2380.         (void) putc('\n',stderr);
  2381.         show_range('y',ymin,ymax);
  2382.         c_token++;
  2383.     }
  2384.     else if (almost_equals(c_token,"zr$ange")) {
  2385.         (void) putc('\n',stderr);
  2386.         show_range('z',zmin,zmax);
  2387.         c_token++;
  2388.     }
  2389.     else if (almost_equals(c_token,"z$ero")) {
  2390.         (void) putc('\n',stderr);
  2391.         show_zero();
  2392.         c_token++;
  2393.     }
  2394.     else if (almost_equals(c_token,"a$ll")) {
  2395.         c_token++;
  2396.         show_version();
  2397.         show_autoscale();
  2398.         show_border();
  2399.         show_boxwidth();
  2400.         show_clip();
  2401.         show_contour();
  2402.         show_dgrid3d();
  2403.         show_mapping();
  2404.           (void) fprintf(stderr,"\tdummy variables are \"%s\" and \"%s\"\n",
  2405.                         dummy_var[0], dummy_var[1]);
  2406.         show_format();
  2407.         show_style("data",data_style);
  2408.         show_style("functions",func_style);
  2409.         show_grid();
  2410.         show_label(0);
  2411.         show_arrow(0);
  2412.         show_key();
  2413.         show_logscale();
  2414.         show_offsets();
  2415.         show_output();
  2416.         show_parametric();
  2417.         show_polar();
  2418.         show_angles();
  2419.         show_samples();
  2420.         show_isosamples();
  2421.         show_view();
  2422.         show_surface();
  2423. #ifndef LITE
  2424.         show_hidden3d();
  2425. #endif
  2426.         show_size();
  2427.         show_term();
  2428.         show_tics(TRUE,TRUE,TRUE);
  2429.         show_time();
  2430.         if (parametric)
  2431.             if (!is_3d_plot)
  2432.                 show_range('t',tmin,tmax);
  2433.             else {
  2434.                 show_range('u',umin,umax);
  2435.                 show_range('v',vmin,vmax);
  2436.             }
  2437.         if (polar)
  2438.           show_range('r',rmin,rmax);
  2439.         show_range('x',xmin,xmax);
  2440.         show_range('y',ymin,ymax);
  2441.         show_range('z',zmin,zmax);
  2442.         show_title();
  2443.         show_xlabel();
  2444.         show_ylabel();
  2445.         show_zlabel();
  2446.         show_zero();
  2447.         show_plot();
  2448.         show_variables();
  2449.         show_functions();
  2450.         c_token++;
  2451.     }
  2452.     else
  2453.         return (FALSE);
  2454.     return (TRUE);
  2455. }
  2456.  
  2457.  
  2458. /*********** support functions for 'show'  **********/
  2459. static void
  2460. show_style(name,style)
  2461. char name[];
  2462. enum PLOT_STYLE style;
  2463. {
  2464.     fprintf(stderr,"\t%s are plotted with ",name);
  2465.     switch (style) {
  2466.         case LINES: fprintf(stderr,"lines\n"); break;
  2467.         case POINTSTYLE: fprintf(stderr,"points\n"); break;
  2468.         case IMPULSES: fprintf(stderr,"impulses\n"); break;
  2469.         case LINESPOINTS: fprintf(stderr,"linespoints\n"); break;
  2470.         case DOTS: fprintf(stderr,"dots\n"); break;
  2471.         case ERRORBARS: fprintf(stderr,"errorbars\n"); break;
  2472.         case BOXES: fprintf(stderr,"boxes\n"); break;
  2473.         case BOXERROR: fprintf(stderr,"boxerrorbars\n"); break;
  2474.         case STEPS: fprintf(stderr,"steps\n"); break;
  2475.     }
  2476. }
  2477.  
  2478. static void
  2479. show_boxwidth()
  2480. {
  2481.     if (boxwidth<0.0)
  2482.         fprintf(stderr,"\tboxwidth is auto\n");
  2483.     else
  2484.         fprintf(stderr,"\tboxwidth is %g\n",boxwidth);
  2485. }
  2486. static void
  2487. show_dgrid3d()
  2488. {
  2489.     if (dgrid3d)
  2490.         fprintf(stderr,"\tdata grid3d is enabled for mesh of size %dx%d, norm=%d\n",
  2491.             dgrid3d_row_fineness,
  2492.             dgrid3d_col_fineness,
  2493.             dgrid3d_norm_value);
  2494.     else
  2495.         fprintf(stderr,"\tdata grid3d is disabled\n");
  2496. }
  2497.  
  2498. static void
  2499. show_range(name,min,max)
  2500. char name;
  2501. double min,max;
  2502. {
  2503.     fprintf(stderr,"\t%crange is [%g : %g]\n",name,min,max);
  2504. }
  2505.  
  2506. static void
  2507. show_zero()
  2508. {
  2509.     fprintf(stderr,"\tzero is %g\n",zero);
  2510. }
  2511.  
  2512. static void
  2513. show_offsets()
  2514. {
  2515.     fprintf(stderr,"\toffsets are %g, %g, %g, %g\n",loff,roff,toff,boff);
  2516. }
  2517.  
  2518. static void
  2519. show_border()
  2520. {
  2521.     fprintf(stderr,"\tborder is %sdrawn\n", draw_border ? "" : "not ");
  2522. }
  2523.  
  2524. static void
  2525. show_output()
  2526. {
  2527.     fprintf(stderr,"\toutput is sent to %s\n",outstr);
  2528. }
  2529.  
  2530. static void
  2531. show_samples()
  2532. {
  2533.     fprintf(stderr,"\tsampling rate is %d, %d\n",samples_1, samples_2);
  2534. }
  2535.  
  2536. static void
  2537. show_isosamples()
  2538. {
  2539.     fprintf(stderr,"\tiso sampling rate is %d, %d\n",
  2540.         iso_samples_1, iso_samples_2);
  2541. }
  2542.  
  2543. static void
  2544. show_surface()
  2545. {
  2546.     fprintf(stderr,"\tsurface is %sdrawn\n", draw_surface ? "" : "not ");
  2547. }
  2548.  
  2549. static void
  2550. show_hidden3d()
  2551. {
  2552. #ifdef LITE
  2553.     printf(" Hidden Line Removal Not Supported in LITE version\n");
  2554. #else
  2555.     fprintf(stderr,"\thidden surface is %s\n", hidden3d ? "removed" : "drawn");
  2556. #endif /* LITE */
  2557. }
  2558.  
  2559. static void
  2560. show_label_contours()
  2561. {
  2562.     fprintf(stderr,"\tcontour line types are %s\n", label_contours ? "varied & labeled" : "all the same");
  2563. }
  2564.  
  2565. static void
  2566. show_view()
  2567. {
  2568.     fprintf(stderr,"\tview is %g rot_x, %g rot_z, %g scale, %g scale_z\n",
  2569.         surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
  2570. }
  2571.  
  2572. static void
  2573. show_size()
  2574. {
  2575.     fprintf(stderr,"\tsize is scaled by %g,%g\n",xsize,ysize);
  2576. }
  2577.  
  2578. static void
  2579. show_title()
  2580. {
  2581.     fprintf(stderr,"\ttitle is \"%s\", offset at %d, %d\n",
  2582.         title,title_xoffset,title_yoffset);
  2583. }
  2584.  
  2585. static void
  2586. show_xlabel()
  2587. {
  2588.     fprintf(stderr,"\txlabel is \"%s\", offset at %d, %d\n",
  2589.         xlabel,xlabel_xoffset,xlabel_yoffset);
  2590. }
  2591.  
  2592. static void
  2593. show_ylabel()
  2594. {
  2595.     fprintf(stderr,"\tylabel is \"%s\", offset at %d, %d\n",
  2596.         ylabel,ylabel_xoffset,ylabel_yoffset);
  2597. }
  2598. static void
  2599. show_zlabel()
  2600. {
  2601.     fprintf(stderr,"\tzlabel is \"%s\", offset at %d, %d\n",
  2602.         zlabel,zlabel_xoffset,zlabel_yoffset);
  2603. }
  2604.  
  2605. static void
  2606. show_xzeroaxis()
  2607. {
  2608.     fprintf(stderr,"\txzeroaxis is %s\n",(xzeroaxis)? "ON" : "OFF");
  2609. }
  2610.  
  2611. static void
  2612. show_yzeroaxis()
  2613. {
  2614.     fprintf(stderr,"\tyzeroaxis is %s\n",(yzeroaxis)? "ON" : "OFF");
  2615. }
  2616.  
  2617. static void
  2618. show_label(tag)
  2619.     int tag;                /* 0 means show all */
  2620. {
  2621.     struct text_label *this_label;
  2622.     TBOOLEAN showed = FALSE;
  2623.  
  2624.     for (this_label = first_label; this_label != NULL;
  2625.         this_label = this_label->next) {
  2626.        if (tag == 0 || tag == this_label->tag) {
  2627.           showed = TRUE;
  2628.           fprintf(stderr,"\tlabel %d \"%s\" at %g,%g,%g ",
  2629.                 this_label->tag, this_label->text, 
  2630.                 this_label->x, this_label->y, this_label->z);
  2631.           switch(this_label->pos) {
  2632.              case LEFT : {
  2633.                 fprintf(stderr,"left");
  2634.                 break;
  2635.              }
  2636.              case CENTRE : {
  2637.                 fprintf(stderr,"centre");
  2638.                 break;
  2639.              }
  2640.              case RIGHT : {
  2641.                 fprintf(stderr,"right");
  2642.                 break;
  2643.              }
  2644.           }
  2645.           fputc('\n',stderr);
  2646.        }
  2647.     }
  2648.     if (tag > 0 && !showed)
  2649.      int_error("label not found", c_token);
  2650. }
  2651.  
  2652. static void
  2653. show_arrow(tag)
  2654.     int tag;                /* 0 means show all */
  2655. {
  2656.     struct arrow_def *this_arrow;
  2657.     TBOOLEAN showed = FALSE;
  2658.  
  2659.     for (this_arrow = first_arrow; this_arrow != NULL;
  2660.         this_arrow = this_arrow->next) {
  2661.        if (tag == 0 || tag == this_arrow->tag) {
  2662.           showed = TRUE;
  2663.           fprintf(stderr,"\tarrow %d from %g,%g,%g to %g,%g,%g%s\n",
  2664.                 this_arrow->tag, 
  2665.                 this_arrow->sx, this_arrow->sy, this_arrow->sz,
  2666.                 this_arrow->ex, this_arrow->ey, this_arrow->ez,
  2667.                 this_arrow->head ? "" : " (nohead)");
  2668.        }
  2669.     }
  2670.     if (tag > 0 && !showed)
  2671.      int_error("arrow not found", c_token);
  2672. }
  2673.  
  2674. static void
  2675. show_grid()
  2676. {
  2677.     fprintf(stderr,"\tgrid is %s\n",(grid)? "ON" : "OFF");
  2678. }
  2679.  
  2680. static void
  2681. show_key()
  2682. {
  2683.     switch (key) {
  2684.         case -1 : 
  2685.             fprintf(stderr,"\tkey is ON\n");
  2686.             break;
  2687.         case 0 :
  2688.             fprintf(stderr,"\tkey is OFF\n");
  2689.             break;
  2690.         case 1 :
  2691.             fprintf(stderr,"\tkey is at %g,%g,%g\n",key_x,key_y,key_z);
  2692.             break;
  2693.     }
  2694. }
  2695.  
  2696. static void
  2697. show_parametric()
  2698. {
  2699.     fprintf(stderr,"\tparametric is %s\n",(parametric)? "ON" : "OFF");
  2700. }
  2701.  
  2702. static void
  2703. show_polar()
  2704. {
  2705.     fprintf(stderr,"\tpolar is %s\n",(polar)? "ON" : "OFF");
  2706. }
  2707.  
  2708. static void
  2709. show_angles()
  2710. {
  2711.     fprintf(stderr,"\tAngles are in ");
  2712.     switch (angles_format) {
  2713.         case ANGLES_RADIANS:
  2714.             fprintf(stderr, "radians\n");
  2715.         break;
  2716.         case ANGLES_DEGREES:
  2717.             fprintf(stderr, "degrees\n");
  2718.         break;
  2719.     }
  2720. }
  2721.  
  2722.  
  2723. static void
  2724. show_tics(showx, showy, showz)
  2725.     TBOOLEAN showx, showy, showz;
  2726. {
  2727.     fprintf(stderr,"\ttics are %s, ",(tic_in)? "IN" : "OUT");
  2728.     fprintf(stderr,"\tticslevel is %g\n",ticslevel);
  2729.  
  2730.     if (showx)
  2731.      show_ticdef(xtics, 'x', &xticdef);
  2732.     if (showy)
  2733.      show_ticdef(ytics, 'y', &yticdef);
  2734.     if (showz)
  2735.      show_ticdef(ztics, 'z', &zticdef);
  2736.     screen_ok = FALSE;
  2737. }
  2738.  
  2739. /* called by show_tics */
  2740. static void
  2741. show_ticdef(tics, axis, tdef)
  2742.     TBOOLEAN tics;            /* xtics ytics or ztics */
  2743.     char axis;            /* 'x' 'y' or 'z' */
  2744.     struct ticdef *tdef;    /* xticdef yticdef or zticdef */
  2745. {
  2746.     register struct ticmark *t;
  2747.  
  2748.     fprintf(stderr, "\t%c-axis tic labelling is ", axis);
  2749.     if (!tics) {
  2750.        fprintf(stderr, "OFF\n");
  2751.        return;
  2752.     }
  2753.  
  2754.     switch(tdef->type) {
  2755.        case TIC_COMPUTED: {
  2756.           fprintf(stderr, "computed automatically\n");
  2757.           break;
  2758.        }
  2759.         case TIC_MONTH: {
  2760.         fprintf(stderr, "Months computed automatically\n");
  2761.         break;
  2762.        }
  2763.         case TIC_DAY:{
  2764.         fprintf(stderr, "Days computed automatically\n");
  2765.         }
  2766.        case TIC_SERIES: {
  2767.           if (tdef->def.series.end == VERYLARGE)
  2768.             fprintf(stderr, "series from %g by %g\n", 
  2769.                   tdef->def.series.start, tdef->def.series.incr);
  2770.           else
  2771.             fprintf(stderr, "series from %g by %g until %g\n", 
  2772.                   tdef->def.series.start, tdef->def.series.incr, 
  2773.                   tdef->def.series.end);
  2774.           break;
  2775.        }
  2776.        case TIC_USER: {
  2777.           fprintf(stderr, "list (");
  2778.           for (t = tdef->def.user; t != NULL; t=t->next) {
  2779.              if (t->label)
  2780.                fprintf(stderr, "\"%s\" ", t->label);
  2781.              if (t->next)
  2782.                fprintf(stderr, "%g, ", t->position);
  2783.              else
  2784.                fprintf(stderr, "%g", t->position);
  2785.           }
  2786.           fprintf(stderr, ")\n");
  2787.           break;
  2788.        }
  2789.        default: {
  2790.           int_error("unknown ticdef type in show_ticdef()", NO_CARET);
  2791.           /* NOTREACHED */
  2792.        }
  2793.     }
  2794. }
  2795.  
  2796. static void
  2797. show_time()
  2798. {
  2799.     fprintf(stderr,"\ttime is %s, offset at %d, %d\n",
  2800.         (timedate)? "ON" : "OFF",
  2801.         time_xoffset,time_yoffset);
  2802. }
  2803.  
  2804. static void
  2805. show_term()
  2806. {
  2807.     fprintf(stderr,"\tterminal type is %s %s\n",
  2808.         term_tbl[term].name, term_options);
  2809. }
  2810.  
  2811. static void
  2812. show_plot()
  2813. {
  2814.     fprintf(stderr,"\tlast plot command was: %s\n",replot_line);
  2815. }
  2816.  
  2817. static void
  2818. show_autoscale()
  2819. {
  2820.     fprintf(stderr,"\tautoscaling is ");
  2821.     if (parametric)
  2822.         if (is_3d_plot)
  2823.             fprintf(stderr,"\tt: %s, ",(autoscale_t)? "ON" : "OFF");
  2824.         else
  2825.             fprintf(stderr,"\tu: %s, v: %s, ",
  2826.                         (autoscale_u)? "ON" : "OFF",
  2827.                         (autoscale_v)? "ON" : "OFF");
  2828.     else fprintf(stderr,"\t");
  2829.  
  2830.     if (polar) fprintf(stderr,"r: %s, ",(autoscale_r)? "ON" : "OFF");
  2831.     fprintf(stderr,"x: %s, ",(autoscale_x)? "ON" : "OFF");
  2832.     fprintf(stderr,"y: %s, ",(autoscale_y)? "ON" : "OFF");
  2833.     fprintf(stderr,"z: %s\n",(autoscale_z)? "ON" : "OFF");
  2834. }
  2835.  
  2836. static void
  2837. show_clip()
  2838. {
  2839.     fprintf(stderr,"\tpoint clip is %s\n",(clip_points)? "ON" : "OFF");
  2840.  
  2841.     if (clip_lines1)
  2842.       fprintf(stderr,
  2843.          "\tdrawing and clipping lines between inrange and outrange points\n");
  2844.     else
  2845.       fprintf(stderr,
  2846.          "\tnot drawing lines between inrange and outrange points\n");
  2847.  
  2848.     if (clip_lines2)
  2849.       fprintf(stderr,
  2850.          "\tdrawing and clipping lines between two outrange points\n");
  2851.     else
  2852.       fprintf(stderr,
  2853.          "\tnot drawing lines between two outrange points\n");
  2854. }
  2855.  
  2856. static void
  2857. show_mapping()
  2858. {
  2859.     fprintf(stderr,"\tmapping for 3-d data is ");
  2860.  
  2861.     switch (mapping3d) {
  2862.         case MAP3D_CARTESIAN:
  2863.             fprintf(stderr,"cartesian\n");
  2864.             break;
  2865.         case MAP3D_SPHERICAL:
  2866.             fprintf(stderr,"spherical\n");
  2867.             break;
  2868.         case MAP3D_CYLINDRICAL:
  2869.             fprintf(stderr,"cylindrical\n");
  2870.             break;
  2871.     }
  2872. }
  2873.  
  2874. static void
  2875. show_contour()
  2876. {
  2877.     fprintf(stderr,"\tcontour for surfaces are %s",
  2878.         (draw_contour)? "drawn" : "not drawn\n");
  2879.  
  2880.     if (draw_contour) {
  2881.             fprintf(stderr, " in %d levels on ", contour_levels);
  2882.         switch (draw_contour) {
  2883.             case CONTOUR_BASE:
  2884.                 fprintf(stderr,"grid base\n");
  2885.                 break;
  2886.             case CONTOUR_SRF:
  2887.                 fprintf(stderr,"surface\n");
  2888.                 break;
  2889.             case CONTOUR_BOTH:
  2890.                 fprintf(stderr,"grid base and surface\n");
  2891.                 break;
  2892.         }
  2893.         switch (contour_kind) {
  2894.             case CONTOUR_KIND_LINEAR:
  2895.                 fprintf(stderr,"\t\tas linear segments\n");
  2896.                 break;
  2897.             case CONTOUR_KIND_CUBIC_SPL:
  2898.                 fprintf(stderr,"\t\tas cubic spline interpolation segments with %d pts\n",
  2899.                     contour_pts);
  2900.                 break;
  2901.             case CONTOUR_KIND_BSPLINE:
  2902.                 fprintf(stderr,"\t\tas bspline approximation segments of order %d with %d pts\n",
  2903.                     contour_order, contour_pts);
  2904.                 break;
  2905.         }
  2906.         switch (levels_kind) {
  2907.             int i;
  2908.             case LEVELS_AUTO:
  2909.                 fprintf(stderr,"\t\t%d automatic levels\n", contour_levels);
  2910.                 break;
  2911.             case LEVELS_DISCRETE:
  2912.                 fprintf(stderr,"\t\t%d discrete levels at ", contour_levels);
  2913.                         fprintf(stderr, "%g", levels_list[0]);
  2914.                 for(i = 1; i < contour_levels; i++)
  2915.                     fprintf(stderr,",%g ", levels_list[i]);
  2916.                 fprintf(stderr,"\n");
  2917.                 break;
  2918.             case LEVELS_INCREMENTAL:
  2919.                 fprintf(stderr,"\t\t%d incremental levels starting at %g, step %g, end %g\n",
  2920.                     contour_levels, levels_list[0], levels_list[1],
  2921.                     levels_list[0]+contour_levels*levels_list[1]);
  2922.                 break;
  2923.         }
  2924.         fprintf(stderr,"\t\tcontour line types are %s\n", label_contours ? "varied" : "all the same");
  2925.     }
  2926. }
  2927.  
  2928. static void
  2929. show_format()
  2930. {
  2931.     fprintf(stderr, "\ttic format is x-axis: \"%s\", y-axis: \"%s\", z-axis: \"%s\"\n",
  2932.         xformat, yformat, zformat);
  2933. }
  2934.  
  2935. static void
  2936. show_logscale()
  2937. {
  2938.     if (is_log_x) {
  2939.         fprintf(stderr,"\tlogscaling x (base %g)", base_log_x);
  2940.         if (is_log_y && is_log_z)
  2941.             fprintf(stderr,", y (base %g) and z (base %g)\n",
  2942.                 base_log_y, base_log_z);
  2943.         else if (is_log_y)
  2944.             fprintf(stderr," and y (base %g)\n", base_log_y);
  2945.         else if (is_log_z)
  2946.             fprintf(stderr," and z (base %g)\n", base_log_z);
  2947.         else
  2948.             fprintf(stderr," only\n");
  2949.     } else if (is_log_y) {
  2950.         fprintf(stderr,"\tlogscaling y (base %g)", base_log_y);
  2951.         if (is_log_z)
  2952.             fprintf(stderr," and z (base %g)\n", base_log_z);
  2953.         else
  2954.             fprintf(stderr," only\n");
  2955.     } else if (is_log_z) {
  2956.         fprintf(stderr,"\tlogscaling z (base %g) only\n", base_log_z);
  2957.     } else {
  2958.         fprintf(stderr,"\tno logscaling\n");
  2959.     }
  2960. }
  2961.  
  2962. static void
  2963. show_variables()
  2964. {
  2965. register struct udvt_entry *udv = first_udv;
  2966. int len;
  2967.  
  2968.     fprintf(stderr,"\n\tVariables:\n");
  2969.     while (udv) {
  2970.          len = instring(udv->udv_name, ' ');
  2971.         fprintf(stderr,"\t%-*s ",len,udv->udv_name);
  2972.         if (udv->udv_undef)
  2973.             fputs("is undefined\n",stderr);
  2974.         else {
  2975.             fputs("= ",stderr);
  2976.             disp_value(stderr,&(udv->udv_value));
  2977.             (void) putc('\n',stderr);
  2978.         }
  2979.         udv = udv->next_udv;
  2980.     }
  2981. }
  2982.  
  2983. char *authors[] = {"Thomas Williams","Colin Kelley"}; /* primary */
  2984. void                /* used by plot.c */
  2985. show_version()
  2986. {
  2987. extern char version[];
  2988. extern char patchlevel[];
  2989. extern char date[];
  2990. extern char copyright[];
  2991. extern char bug_email[];
  2992. int x;
  2993. long time();
  2994.  
  2995.     x = time((long *)NULL) & 1;
  2996.     fprintf(stderr,"\n\t%s\n\t%sversion \n\t%s\n",
  2997.         PROGRAM, OS, version); 
  2998.     fprintf(stderr,"\tpatchlevel %s\n",patchlevel);
  2999.      fprintf(stderr, "\tlast modified %s\n", date);
  3000.     fprintf(stderr,"\n\t%s   %s, %s\n", copyright,authors[x],authors[1-x]);
  3001.     fprintf(stderr, "\n\tSend bugs and comments to %s\n", bug_email);
  3002. }
  3003.